函数

箭头函数和普通函数的区别

  1. 语法更简洁
  2. 不会创建this
  3. 不能作为构造函数来使用,this来自声明时的上下文
  4. 没有arguments protoType属性
  5. 不能作为生成器函数使用

函数方法 call apply bind

call方法接收多个参数,第一个参数是指定的this,之后的参数为函数的入参
apply方法接收两个参数,第一个参数是指定的this,函数的参数列表
bind方法接收两个参数,第一个是指定的this, 第二个是函数或函数表达式, 方法不会执行并返回一个新的函数

call实现

1
2
3
4
5
6
7
8
Function.prototype.call2 = function(content) {
let context = content || window
context.fn = this
const args = Array.from(arguments).slice(1).map(a => `'${a}'`)
const result = eval(`content.fn(${args.join(',')})`)
delete context.fn
return result
}

apply实现

1
2
3
4
5
6
7
8
9
10
11
12
13
Function.prototype.apply2 = function(content, arr) {
let context = content || window
context.fn = this
let result
if (!arr) {
result = eval(`content.fn()`)
} else {
const args = arr.map(a => `'${a}'`)
result = eval(`content.fn(${args.join(',')})`)
}
delete context.fn
return result
}

bind实现

1
2
3
4
5
6
7
8
9
10
11
12
Function.prototype.bind2 = function(content) {
const self = this
const args = Array.from(arguments).slice(1)
const fnc = function() {}
const fBound = function () {
const bindArg = Array.from(arguments)
return self.apply(this instanceof fnc ? this : content, args.concat(bindArg))
}
fnc.prototype = this.prototype;
fBound.prototype = new fnc();
return fBound;
}

new 关键字

  1. 创建一个新的对象。
  2. 将构造函数的作用域赋给新对象(所以this就指向了这个新的对象)。
  3. 执行构造函数中的代码(为我们这个新对象添加相应的属性)。这些属性就是构造函数里面的属性,我们通过这一步将构造函数的属性添加到新对象里面。
  4. 最后返回这个新对象。

实现

1
2
3
4
5
6
7
function _new(fn) {
const args = Array.from(arguments).slice(1)
const newObj = {}
newObj.__proto__ = fn.prototype
fn.apply(newObj, args)
return newObj
}