30道大概率会考到的题( 11-15题)
本章内容
- 11,箭头函数特点
- 12,CSS盒模型
- 13,Vue组件data为什么必须是函数
- 14,JS判断数组的方法
- 15,JS的宏任务、微任务
11,箭头函数特点
1,箭头函数是匿名函数,不能作为构造函数
let Person = () => {
// ...
}
let p1 = new Person() // Person is not a constructor
2,箭头函数不能使用arguments, 用rest取代
let foo = (...arr) => {
console.log(arr)
}
foo([1, 2, 3, 4, 5])
// [0, 1, 2, 3, 4, 5]
3, 箭头函数默认绑定外层this, 不能用call、bind、apply等修改this.
3.1, 对象中函数调用的this
let obj = {
name: 'Jerry',
sayHello: function() {
console.log(this.name)
}
}
obj.sayHello() // Jerry
obj.sayHello.call(obj) // Jerry
// this 指向 obj
以上代码,第1种调用方法是第2种调用方法的语法糖,第2种调用方法是最完整的调用方法。第二种调用方法可以修改this指向
let obj = {
name: 'Jerry',
sayHello: function() {
console.log(this.name)
}
}
let obj1 = {
name: 'Tom'
}
obj.sayHello.call(obj1) // Tom
// this 指向 obj1
3.2,构造函数中this
function Person(name) {
this.name = name
}
let p1 = new Person("Jerry") // this 指向 p1对象
3.3,window.setTimeout()/setInterval()函数中的this
let obj = {
name: 'Jerry',
sayHello: function() {
window.setTimeout(function() {
console.log(this) // window对象
})
}
}
obj.sayHello.call(obj)
3.4,箭头函数this
let obj = {
name: 'Jerry',
sayHello: () => {
console.log(this) // window
}
}
obj.sayHello()
let obj = {
name: 'Jerry',
sayHello: () => {
console.log(this)
}
}
obj.sayHello.call({
name: 'Tom'
})
let obj = {
name: 'Jerry',
sayHello: function() {
window.setTimeout(_ => {
console.log(this) // obj
})
}
}
obj.sayHello.call(obj)
// window.setTimeout()中函数里的this默认是window,可以通过箭头函数改变this指向
12,css盒模型
css盒模型:W3C(标准)盒模型、IE盒模型
标准盒模型: 总宽/高度 = 内容 + padding + border + margin

IE盒模型:总宽/高 = 内容(内容包含padding+border) + margin

IE盒模型和W3C盒模型区别是IE盒模型的内容包含了border和padding
13,Vue组件data为什么必须是函数
new Vue()实例中, data可以直接是一个对象,而在vue组件中, data必须是一个函数,因为组件是可以复用的,JS里对象是引用关系, 如果组件data是一个对象, 子组件中的data属性值会互相污染, 产生副作用。
所以组件中的data必须是一个函数, 每个实例可以维护一份被返回对象的独立拷贝。new Vue实例不会被复不存在以上问题。
14,js判断数组的方法
- Object.prototype.toString.call()
- instanceof
- Array.isArray()
Object.prototype.toString.call()
能准确的检测所有的数据类型
每一个继承Object的对象都有一个toString方法,如果toString方法没有被重写,会返回[Object type], type为对象的类型。
const arr = ["a", "b"]
arr.toString() // => "a, b"
Object.prototype.toString.call(arr) // => "[Object Array]"
instanceof
能检测array、function、object类型
instanceof用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上,即 A 是否为 B 的实例:A instanceof B
1 instanceof Number // false
'str' instanceof String // false
true instanceof Boolean // false
[1,2,3] instanceof Array // true
function () {} instanceof Function // true
{} instanceof Object // true
instanceof 的缺点:是否处于原型链上的判断方法不严谨
instanceof 方法判断的是是否处于原型链上,而不是是不是处于原型链最后一位,所以会出现以下情况:
var arr = [1, 2, 3]
arr instanceof Array // true
arr instanceof Object // true
function fn() {}
fn instanceof Function // true
fn instanceof Object // true
所有原型链的尽头都是Object
Array.isArray()
用于判断对象是否为数组
Array.isArray()是ES5推出的,IE8及以下不支持此API,使用时应考虑兼容
Array.isArray([1, 2, 3, 4]) // true
Array.isArray({a: 1}) // false
Array.isArray(new Array) // true
Array.isArray("string") // false
if(typeof Array.isArray != 'function') {
Array.isArray = function(obj){
return Object.prototype.toString.call(obj) == '[object Array]'
}
}
15,Js的宏任务、微任务
JS的执行机制:附图做参考(原文地址:https://www.jianshu.com/p/0d2d42fbe1dc)

上图内容概括为:
- 同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数
- 当指定的事情完成时,Event Table(事件表)会将这个函数移入Event Queue(事件队列)。
- 主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
- 上述过程会不断重复,也就是常说的Event Loop(事件循环)。
JS的宏任务、微任务:
ES6规范中,宏任务由宿主发起,微任务由JS自身发起。
在ES5之后,JS引入了Promise,不需要浏览器,JS引擎自身也能发起异步任务了

微任务执行时机比宏任务要早

理解JavaScript执行机制实例:
// 示例1
console.log(1)
setTimeout(() => {
console.log(2)
}, 0)
new Promise((resolve) => {
console.log(3)
resolve()
})
.then(() => {
console.log(4)
})
.then(() => {
console.log(5)
})
console.log(6)
以上代码输出:1 3 6 4 5 2
// 示例2
console.log(1)
async function async1() {
await async2()
console.log(2)
}
async function async2() {
console.log(3)
}
async1()
setTimeout(function() {
console.log(4)
}, 0)
new Promise(resolve => {
console.log(5)
resolve()
})
.then(function() {
console.log(6)
})
.then(function() {
console.log(7)
})
console.log(8)
以上代码输出:1 3 5 8 2 6 7 4
网友评论