The difference between the arrow function and the normal this function
- Point to different
Ordinary functionalthisRefers to the object at the time of the method call, which can be changed by call, apply, or bindthisThe pointing arrow function will not create its ownthisIt inherits only from the layer above its scopethis. Call, aply, bind cannot be changedthisPointing can only be used to pass parametersCopy the code
var obj = {
a: 10.b: () = > {
console.log(this.a) // undefined
console.log(this) // Window
},
c: function () {
console.log(this.a) / / 10
console.log(this) // {a:10, b:()=>{},c:f()}}}console.log(obj.b())
console.log(obj.c())
Copy the code
- Arrow functions have no prototype
var a = () = >{}console.log('prototype', a) / / () = > {}
console.log('prototype', a.prototype) // undefined
Copy the code
- Arrow function can’t bind argument, rest argument instead… To solve the
let A = () => { console.log(arguments); // arguments is not defined } A(1, 2, 3, 4, 5, 8); let B = (... rest) => { console.log(rest); // [1, 2, 3, 4, 5, 8] console.log(Object.prototype.toString.call(rest)) // [object Array] } B(1, 2, 3, 4, 5, 8);Copy the code
This also illustrates rest(…) in ES6. Argument, which returns an array type, unlike arguments, which returns an array of classes
- Arrow functions are anonymous and cannot be used as constructors. They cannot be new
Can't instantiate: Without its own this, you can't call Call and apply to change this reference. The new command assigns the constructor's prototype value to _proto of the new objectCopy the code
Hand write call, apply, bind
/ / call
Function.prototype._call = function (context, ... args) {
const fn = Symbol('fn')
let ctx = context || window
ctx.fn = this
let res = args.length > 0? ctx.fn(... args) : ctx.fn()delete ctx.fn
return res
}
/ / the apply
Function.prototype._apply = function (context, args = []) {
const fn = Symbol('fn')
let ctx = context || window
ctx.fn = this
if(! (args && argsinstanceof Array)) {
throw ('Please pass in an array')}let res = args.length > 0? ctx.fn(... args) : ctx.fn()delete ctx.fn
return res
}
/ / the bind
Function.prototype._bind = function (context, ... args) {
let that = this
return function () {
returnthat._call(context, ... args) } }var name = "1";
var obj = {
name: 2.prop: {
name: 3.getName: function (age, s) {
return {
name: this.name,
age: age,
s: s
}
}
}
}
console.log(obj.prop.getName(3.4)); // 3, 3, 4
console.log(obj.prop.getName.call(obj, 3.4)); //this is obj 2, 3, 4
console.log('_call achieve', obj.prop.getName._call(this.3.4)); // This is window 1, 3, 4
console.log('_apply achieve', obj.prop.getName._apply(this[2.3])); // This is window 1, 2, 3
let bindHandle = obj.prop.getName._bind(this.2.3)
console.log('bindHandle()', bindHandle())// This is window 1, 2, 3
Copy the code
Class arrays are converted to arrays
let A = function () {
console.log('Array of classes'.arguments); // Arguments(6) [1, 2, 3]
console.log('law a'.Array.prototype.slice.call(arguments)); / / [1, 2, 3]
console.log('method of 2'.Array.from(arguments)); / / [1, 2, 3]
console.log('three', [...arguments]); / / [1, 2, 3]
}
A(1.2.3);
Copy the code
Writing thinking
- The implementation of bind takes advantage of closures and lazy execution (Curritization).
Closure article output address
Currified article address