其他分享
首页 > 其他分享> > js基本问题

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元素的事件冒泡。
优点:

  1. 大量减少内存占用,减少事件注册。
  2. 新增元素实现动态绑定事件
    (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