js基本问题
作者:互联网
JS
1.this指向问题
this指向更深入了解地址
(1)函数调用,this指向它的调用者
function foo() {
console.log(this.bar);
}
var bar = "bar1";
var o2 = {bar: "bar2", foo: foo};
var o3 = {bar: "bar3", foo: foo};
foo(); // bar1
o2.foo(); // bar2
foo.call(o3); // bar3
(2)
var name = 'Nicolas';
function Person(){
this.name = 'Smiley';
this.sayName=function(){
console.log(this);
console.log(this.name);
};
setTimeout(this.sayName, 0); // 第二次输出
}
var person = new Person();
person.sayName(); // 第一次输出
第一次输出Person, Smiley
第二次输出window,Nicolas。 尽管setTimeout是在构造函数中定义的,但是调用的时候,是在window中调用。
(3)
function Person() {
this.name = "Smiley";
this.sayName = function(){
console.log(this);
console.log(this.name);
};
}
let person = new Person();
person.sayName.call({name: "Nicolas"});
输出 {name: “Nicolas”}和”Nicolas”
call改变this的指向,call中的内容就是this
(4)
function Person() {
this.name = "Smiley";
this.sayName = function(){
console.log(this);
console.log(this.name);
};
}
let person = new Person();
// 注意sayName后面没有括号,因此不是调用sayName方法
let sayNameCopy = person.sayName;
sayNameCopy();
输出window和undefined
改变调用方法,不直接调用:改用赋值后调用,此时this的指向为window
(5)
function Person() {
this.name = "Smiley";
this.sayName = ()=> {
console.log(this);
console.log(this.name);
};
}
let person = new Person();
person.sayName.call({name: "Nicolas"});
输出 Person和"Smiley"
这是因为箭头函数并没有自己的this,被定义在哪里,this就指向谁,且优先级比显式调用高,且this方向不可改变,箭头函数如果无调用者,指向Windows
2.img标签的title和alt属性有什么区别
alt:图片加载失败时,显示在网页上的替代文字
title:鼠标(手机端该属性无意义)放在图片上时显示的文字
图片懒加载
原理:一张图片就是一个标签,浏览器是否发起请求图片是根据<img>
的src属性,所以实现懒加载的关键就是,在图片没有进入可视区域时,先不给<img>
的src赋值,这样浏览器就不会发送请求了,等到图片进入可视区域再给src赋值。
实现:
1.加载loading图片
2.判断哪些图片要加载【重点】
3.隐形加载图片
4.替换真图片
步骤:
innerHeight 窗口的文档显示区的高度不包括菜单栏
scrollTop 鼠标滚过的高度
offsetTop 距离浏览器顶部的高度
innerHeight + scrollTop > offsetTop 开始加载
3.继承的方式有那几种?
4.reduce
详细讲解
prev:上次调用函数的返回值
cur:当前元素
index:当前元素索引
arr:被遍历的数组
let arr = [1, 2, 3, 4];
let sum = arr.reduce(function(prev, cur, index, arr) {
return prev + cur;
},5)
第一个数字是5,从5开始加 5+1+2+3+4
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let nameNum = names.reduce((pre,cur)=>{
if(cur in pre){
//对象的访问方法,用中括号
pre[cur]++
}else{
pre[cur] = 1
}
return pre
},{})
console.log(nameNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
5.计算数组的深度
const arr=[[2,[2,6]],2]
let tem=[]
function deep(arr){
for (let i = 0; i < arr.length; i++) {
if (arr[i] instanceof Array) { // 判断是否是数组
deep(arr[i])
}else{
tem.push(arr[i])
}
}
return tem
}
console.log(deep(arr))//[2,2,6,2]
6.[].concat.apply 数组扁平化
const arr = [1,2,[3,4,5,[6,7],8],9,10,[11,[12,13]]];
const flatten = (arr) => {
while (arr.some(item => Array.isArray(item))){
arr = [].concat.apply([], arr);
}
return arr;
}
apply改变this的指向,将arr拼接到【 】中
apply(this,[arr1,arrr2,arr3])这样来传参的,它的第二个参数就是以一个数组形式进行传参,所以很明显很符合我们之前的题目设定,所以[[12,21],[1,2,3],[2,3,4]]=>[arr1,arrr2,arr3] ,arr1=>[12,21]; arr2=>[1,2,3]; arr3=>[2,3,4]; apply会分别依次把参数传过去,之后运用concat来把这些单独的数组相连接变成了一个数组。新数组元素下标从0开始。
7.常见Plugin
html-webpack-plugin
生成 html 文件。将 webpack 中entry配置的相关入口 chunk 和 extract-text-webpack-plugin抽取的 css 样式 插入到该插件提供的template或者templateContent配置项指定的内容基础上生成一个 html 文件,具体插入方式是将样式link插入到head元素中,script插入到head或者body中。
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.join(__dirname, '/index.html'),
minify: {
// 压缩HTML文件
removeComments: true, // 移除HTML中的注释
collapseWhitespace: true, // 删除空白符与换行符
minifyCSS: true, // 压缩内联css
},
inject: true,
}),
]
inject 有四个选项值
true:默认值,script 标签位于 html 文件的 body 底部
body:script 标签位于 html 文件的 body 底部(同 true)
head:script 标签位于 head 标签内
false:不插入生成的 js 文件,只是单纯的生成一个 html 文件
clean-webpack-plugin
clean-webpack-plugin 用于在打包前清理上一次项目生成的 bundle 文件,它会根据 output.path 自动清理文件夹;这个插件在生产环境用的频率非常高,因为生产环境经常会通过 hash 生成很多 bundle 文件,如果不进行清理的话每次都会生成新的,导致文件夹非常庞大。
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, '/index.html'),
}),
new CleanWebpackPlugin(), // 所要清理的文件夹名称
]
extract-text-webpack-plugin
将 css 成生文件,而非内联 。该插件的主要是为了抽离 css 样式,防止将样式打包在 js 中引起页面样式加载错乱的现象
const ExtractTextPlugin = require('extract-text-webpack-plugin')
lugins: [
// 将css分离到/dist文件夹下的css文件夹中的index.css
new ExtractTextPlugin('css/index.css'),
]
8.前端优化
(1)精灵图,防止多次加载图片
(2)将 CSS放在 HEAD中,如果将 CSS放在其他地方比如 BODY中,则浏览器有可能还未下载和解析到 CSS就已经开始渲染页面了,这就导致页面由无 CSS状态跳转到 CSS状态,用户体验比较糟糕。除此之外,有些浏览器会在 CSS下载完成后才开始渲染页面,如果 CSS放在靠下的位置则会导致浏览器将渲染时间推迟。
(3)减少作用域链查找,声明局部作用域
(4)事件委托
事件委托其实就是利用JS事件 冒泡机制把原本需要绑定在子元素的响应事件(click、keydown……)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。
优点:
- 大量减少内存占用,减少事件注册。
- 新增元素实现动态绑定事件
(5)滚动事件,防抖节流
(6)使用 HTTP2
HTTP2 相比 HTTP1.1 有如下几个优点:
解析速度快
服务器解析 HTTP1.1 的请求时,必须不断地读入字节,直到遇到分隔符 CRLF 为止。
而解析 HTTP2 的请求就不用这么麻烦,因为 HTTP2 是基于帧的协议,每个帧都有表示帧长度的字段。
多路复用
HTTP1.1 如果要同时发起多个请求,就得建立多个 TCP 连接,因为一个 TCP 连接同时只能处理一个 HTTP1.1 的请求。
在 HTTP2 上,多个请求可以共用一个 TCP 连接,这称为多路复用。同一个请求和响应用一个流来表示,并有唯一的流 ID 来标识。
多个请求和响应在 TCP 连接中可以乱序发送,到达目的地后再通过流 ID 重新组建。
首部压缩
HTTP2 提供了首部压缩功能。
如果可以把相同的首部存储起来,仅发送它们之间不同的部分,就可以节省不少的流量,加快请求的时间。
HTTP/2 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键值对,对于相同的数据,不再通过每次请求和响应发送。
优先级
HTTP2 可以对比较紧急的请求设置一个较高的优先级,服务器在收到这样的请求后,可以优先处理。
流量控制
由于一个 TCP 连接流量带宽(根据客户端到服务器的网络带宽而定)是固定的,当有多个请求并发时,一个请求占的流量多,另一个请求占的流量就会少。流量控制可以对不同的流的流量进行精确控制。
前端优化具体
(7)图片懒加载
const img = document.querySelector(‘img’)
img.src = img.dataset.src
将img标签的data-souce放置图片的真实地址
标签:基本,arr,console,name,sayName,问题,let,js,log 来源: https://blog.csdn.net/kukudeshaonian/article/details/122031090