On the differences between Notes and arrow arrow and function of normal function function, NA scene

On the differences between Notes and arrow arrow and function of normal function function, NA scene

Arrow function is ES6 the API, I believe many people know, because it is more concise syntax relative to a normal function, loved by everyone. This is the level of understanding of our daily development API has been used, most of the students but it is still not deep enough ...

The difference between a normal function and arrow functions:

Arrow pointing function of this rule:

1. No function arrow prototype(prototype), so that the arrow does not have this function

let a = () =>{};
console.log(a.prototype); // undefined

2. this arrow pointing function, when defined in this inherited from a common function of the first layer.

Chestnut following functions in a function defined in an arrow, and then perform another function in the function arrow.

let a,
  barObj = { msg: 'bar的this指向' };
fooObj = { msg: 'foo的this指向' };
bar.call(barObj); // 将bar的this指向barObj
foo.call(fooObj); // 将foo的this指向fooObj
function foo() {
  a(); // 结果:{ msg: 'bar的this指向' }
}
function bar() {
  a = () => {
    console.log(this, 'this指向定义的时候外层第一个普通函数'); // 
  }; // 在bar中定义 this继承于bar函数的this指向
}

It can be derived from the above two chestnut

  1. Where the arrows point to the definition of this function is the outer layer of the first general function, with the use of location does not matter .
  2. this is a normal function of the inherited point to change, this will follow the arrow points to the function change

3 can not directly modify an arrow pointing to this function

Last chestnuts in the function foo changed a bit, try to directly modify the function of this pointing arrow.

let fnObj = { msg: '尝试直接修改箭头函数的this指向' };
function foo() {
  a.call(fnObj); // 结果:{ msg: 'bar的this指向' }
}

Clearly, call display failed to bind this point, including aaply, bind all the same.

They (call, aaply, bind) will be silently ignored the first argument, but the normal parameter passing.

Then I went through implicit binding to attempt also fails, new call will complain that this later say.

SO, an arrow can not directly modify its function this point .

Fortunately, we can modify the function of the arrow pointing through an indirect form:

To modify inherited a normal function of this point, then this function arrow pointing will also change , which demonstrates on a chestnut.

bar.call(barObj); // 将bar普通函数的this指向barObj 然后内部的箭头函数也会指向barObj

4. arrow ordinary function is not a function of the outer layer, and a non-strict model strict mode it will point to this window(global object)

Well, this question is actually put forward by the interviewer, then I think the arrow function rule is: this arrow pointing to inherit this function from the first outer layer of an ordinary function, it seems really loose (less a definition time), if the interviewer asked me: define and execute a common function is not the same, the point where it definitely Xiecai ...

Since this function arrow pointing at the point of definition inherited from this first outer layer of an ordinary function, then:

When the arrow is not a function of the outer layer of ordinary function, this will point to where it is ?

I have written here before with this binding rules are not the same (do not understand the point you can go look), the default binding rules common functions are:

In non-strict mode, the default global object bound to this point, at this point undefined strict mode

If the arrow is not a function of the outer layer of ordinary function inheritance, it points to this rule :

After testing, the arrow function in the global scope, under strict and non-strict mode it will point to this window(global objects) .

Tip: When testing found that strict mode in the middle of a statement is invalid and must take effect at the beginning of the statement will be global / functions :

a = 1;
'use strict'; // 严格模式无效 必须在一开始就声明严格模式
b = 2; // 不报错

Arrow function

arrow function arguments

this function arrow points to the overall situation will be reported using the wrong arguments undeclared

If this function is pointing arrow window(global objects) use argumentswill complain, not declared arguments.

let b = () => {
  console.log(arguments);
};
b(1, 2, 3, 4); // Uncaught ReferenceError: arguments is not defined

PS: If you declare a global variable arguments, it does not complain, but why did you do it?

When this function arrow points to an ordinary function, it argumensinherits from the ordinary function

The above is the first case: this function arrow points to the global object, will report errors arguments undeclared.

The second situation is: this function if the arrow points to an ordinary function, it argumensinherits from the ordinary function.

function bar() {
  console.log(arguments); // ['外层第二个普通函数的参数']
  bb('外层第一个普通函数的参数');
  function bb() {
    console.log(arguments); // ["外层第一个普通函数的参数"]
    let a = () => {
      console.log(arguments, 'arguments继承this指向的那个普通函数'); // ["外层第一个普通函数的参数"]
    };
    a('箭头函数的参数'); // this指向bb
  }
}
bar('外层第二个普通函数的参数');

So how to get the arrow function variable number of parameters? The answer is: ES6 the rest parameters ( ...the extension)

get extra rest parameter function parameters

This API is for ES6, a function for acquiring an array of a variable number of parameters, the API is used instead argumentsof, API is used as follows:

let a = (first, ...abc) => {
  console.log(first, abc); // 1 [2, 3, 4]
};
a(1, 2, 3, 4);

The above shows chestnuts, obtaining a first determined parameter, and an example of the other remaining parameters received with a variable function other.

All usage parameters, rest of the parameters may be directly receive function with respect to the argumentsadvantages:

  1. Arrow function and a normal function can be used.
  2. More flexible, the number of reception parameters is fully customizable.
  3. Better readability

    Parameters are defined in the function parentheses, will not be a sudden arguments, before just to see when, really strange!

  4. rest is a real array, you can use the API array.

    Because argumentsan array of objects of class, some people think it is a real array, so there will be the following scenario:

    arguments.push(0); // arguments.push is not a function

    As if we need to use an array of API, you need to use the extension /Array.from to convert it into a true array:

    arguments = [...arguments]; 或者 :arguments = Array.from(arguments);

    rest parameters Two things to note :

  5. rest must be the last parameter of the function:

    let a = (first, ...rest, three) => {
      console.log(first, rest,three); // 报错:Rest parameter must be last formal parameter
    };
    a(1, 2, 3, 4);
  6. length property function, excluding rest parameter

    (function(...a) {}).length  // 0
    (function(a, ...b) {}).length  // 1

Operators can also be used to expand the array, here is the Ruan Yifeng teacher documents

PS: I feel it write more, but prefer to point to a clear knowledge ...

Use newcall arrow function error

No matter where thsi arrow pointing function, using the newcall arrow function will error, because there is no function arrowconstructor

let a = () => {};
let b = new  a(); // a is not a constructor

Arrow function does not support new.target:

new.targetES6 property is newly introduced, by ordinary function if newcalled, new.targetit will return a reference to the function.

This property is primarily: to determine whether the constructor for the new call.

  1. this function of the global object arrow, use the arrow functions will be given in the function arrow

    let a = () => {
      console.log(new.target); // 报错:new.target 不允许在这里使用
    };
    a();
  2. this function arrow points to an ordinary function, it new.target is pointing to the ordinary functions of reference.

    new bb();
    function bb() {
      let a = () => {
        console.log(new.target); // 指向函数bb:function bb(){...}
      };
      a();
    }

More about new.targetyou can look at Ruan Yifeng teacher about this part of the explanation .

Arrow function does not support renaming function parameters, function parameters common functions support renaming

The following example, function parameters common support renaming function, appears later will overwrite the previous arrow throws an error function:

function func1(a, a) {
  console.log(a, arguments); // 2 [1,2]
}

var func2 = (a,a) => {
  console.log(a); // 报错:在此上下文中不允许重复参数名称
};
func1(1, 2); func2(1, 2);

Arrow function relative to the normal function syntax is more simple and elegant:

Reason, different grammatical, also is the difference between the two of them!

  1. Arrow functions are anonymous function, and do not writefunction

  2. Only when a parameter can omit the parentheses:

    var f = a => a; // 传入a 返回a
  3. When the function is only one statement can be omitted {}andreturn

    var f = (a,b,c) => a; // 传入a,b,c 返回a
  4. Simplify the callback function, let your callback function more elegant:
[1,2,3].map(function (x) {
  return x * x;
}); // 普通函数写法 
[1,2,3].map(x => x * x); // 箭头函数只需要一行

Notes arrow and function of NA scene

Notes arrow function

  1. A statement returns the object literal, and needs braces, or simply write multiple statements of returnthe form,

    Like func otherwise demonstrated, the braces will be parsed as multiple statements braces, can not be resolved correctly

var func1 = () => { foo: 1 }; // 想返回一个对象,花括号被当成多条语句来解析,执行后返回undefined
var func2 = () => ({foo: 1}); // 用圆括号是正确的写法
var func2 = () => {
  return {
    foo: 1 // 更推荐直接当成多条语句的形式来写,可读性高
  };
};
  1. Arrow line function can not change between the parameter and the arrow!
var func = ()
           => 1;  // 报错: Unexpected token =>
  1. Resolution order function relative forward arrow

MDN: Although not an arrow arrow function operator, but has the conventional function arrows different special function operator precedence parsing rules

let a = false || function() {}; // ok
let b = false || () => {}; // Malformed arrow function parameter list
let c = false || (() => {}); // ok

Arrow function NA scene:

Around two things: this accident and code readability arrow pointing function.

  1. Literal definition of the method, the accident this point.

Because the simple function of the arrow

const obj = {
  array: [1, 2, 3],
  sum: () => {
    // 根据上文学到的:外层没有普通函数this会指向全局对象
    return this.array.push('全局对象下没有array,这里会报错'); // 找不到push方法
  }
};
obj.sum();

Chestnut above using normal function or ES6 shorthand method of defining a method, there is no problem:

// 这两种写法是等价的
sum() {
  return this.array.push('this指向obj');
}
sum: function() {
  return this.array.push('this指向obj');
}

Another is to define the method prototype ordinary function of time, usually defined outside the ordinary functions, such as inheritance when / Add methods.

This time because there is no definition within the ordinary functions, so this will point to other common functions, or the global object, causing bug!

  1. Dynamic this callback function

The following is a modification operation dom text, as this refers to the error, resulting in modification failed:

const button = document.getElementById('myButton');
button.addEventListener('click', () => {
    this.innerHTML = 'Clicked button'; // this又指向了全局
});

As you know, replaced by an ordinary function has become.

  1. Consider the code readability, use an ordinary function

    • Complex function body:

      Function is manifested by arrow symbols using a plurality of ternary operator is not wrapped, have written in one line, very sick!

    • The number of lines more
    • A large number of internal functions operate

Article content summary:

The difference between a normal function and arrow functions:

  1. Function has no arrow prototype(prototype), so that the arrow does not have this function
  2. this arrow inherited this function from the first layer at the time of an ordinary function definition.
  3. If the arrow is not an ordinary function function layer, and a non-strict model strict mode it will point to this window(global object)
  4. this arrow points to the function itself can not be changed, but you can modify it to inherit this object.
  5. this function arrow points to the overall situation will be reported using the wrong arguments undeclared.
  6. When this function arrow points to an ordinary function, it argumensinherits from the ordinary function
  7. Use newcall arrow function will complain, because there is no function arrowconstructor
  8. Arrow function does not supportnew.target
  9. Arrow function does not support renaming function parameters, function parameters common functions support renaming
  10. Arrow function relative to the normal function syntax is more simple and elegant

Notes arrow and function of NA scene

Arrow function Note :

  1. Arrow function returns a statement object literal, we need to add brackets
  2. Arrows between the parameter and the function can not change the line of arrow
  3. Arrow resolution order function relative ||forward

Not Applicable scene : the readability of this unexpected pointing arrow and function code.


Epilogue

Painstaking, it can be said to be very wide, anyway, for the first time when I was asked to think of this arrow can only function is inherited, and the simplicity of the syntax, the other I do not know, hope this article help Fellow students acquire knowledge.

PS: Currently looking for work, and seeking to push within the bigwigs, senior front-end, partial JS, Vue, Shanghai Yangpu.

Blog , the front end of the accumulation of documents , the public number , GitHub , WX: OBkoro1, E-mail: [email protected]

More 2019.03.22

References:

MDN function arrow

Ruan Yifeng entry -ES6

When you can not use the arrow functions?

Guess you like

Origin blog.51cto.com/14504220/2430234