es6箭头函数

79次阅读

共计 2491 个字符,预计需要花费 7 分钟才能阅读完成。

箭头函数

es6 中添加了函数新的定义语法——箭头函数 ,当有大于一个形参的时候,必须使用() 代表部分参数,函数体大于一行时,必须使用 {} 将函数体括起来,并使用 return 返回。

箭头函数不会创建自己的 this

箭头函数会在自己的作用域链上的上一层寻找 this。所以箭头函数会在定义时找到自己外层的 this,并继承这个 this 的值。在后面的任何操作中,this 的值都不会改变。
箭头函数的实现

var a =  1;
function func() {setTimeout(() => {console.log(this.a);
    }, 1000);
}
func.call({a: 2});
// 2

setTimeout使用的是箭头函数,所以 this 在定义的时候就确定了,继为外层 func 的 this 的值。在函数执行的时候,通过 call 改变了 func 的 this 指向{a:2}, 所以箭头函数继承 func 在执行环境中的指向,所以打印输出 2。

普通函数的实现

var a =  1;
let func = function () {setTimeout(function () 
    {console.log(this.a);
    }, 1000);
}
func.call({a: 2});
//1

setTimeout使用的是普通的函数,所以其 this 指向为函数运行时的所在的作用域。在 1 秒之后函数是在全局作用域中执行的,此时 this 指向 window 对象,所以输出为 1。

不能定义对象方法

let obj = {
    name: 'lisi',
    a: function() 
    {console.log(this.name);
    },
    b: () =>{console.log(this.name);
        this.a();}
}

let name = "zhangsan";
obj.a();
obj.b();

//lisi
//zhangsan
//Uncaught TypeError: this.a is not a function

JS 中对象方法的定义方式是在对象上定义一个指向函数的属性,当方法被调用的时候,方法内的 this 就会指向方法所属的对象。所以方法 a 中的 this 指向对象 obj。但是在 obj 对象的 {} 无法形成一个单独的作用域,所以 obj 是在 window 作用域中,方法 b 为箭头函数,指向上层 obj 的 this === window,所以 a 方法输出 obj 的 name 属性,b 方法输出全局 name 的值。且由于全局作用域上没有 a 方法,所以 this.a()执行报错。所以用箭头函数定义对象方法时,不会有预想的输出。当要定义对象方法时,请使用函数表达式或者方法简写(es6)。

箭头函数不能当作构造函数

function Person (name, age) {
     this.age = age;
     this.name = name;
}
let person = new Person('lisi', 23);
console.log(person.name, person.age);
//lisi 23

js 在 new 生成一个新的实例对象的时候,首先在内部生成一个新的空对象,然后将 this 指向该对象,接着执行构造函数的指令,最后将该对象作为实例返回。

let Person = (name, age) => {
    this.name = name;
    this.age = age;
}
let person = new Person('lisi', 23);
console.log(person.name, person.age);
//Uncaught TypeError: Person is not a constructor

但是箭头函数并没有自己的 this, 其 this 是继承了外层执行环境的 this,且不能改变,因此不能作为构造函数,此时,js 引擎会在报错。Person 不是一个构造函数。

this 的指向改变

箭头函数 this 的指向不会因为 call()、bind()、apply()而改变

var a = 'haha'
let func = () =>{console.log(this.a)
}
func();
func.bind({a: 1})()
func.apply({a: 2});
func.call({a: 3});
//haha
//haha
//haha
//haha

在 js 中,可以使用 bind()、apply()、call()来动态绑定函数的作用域,但是在箭头函数中,this 由于已经固化在上层作用域链上,所以这三种方法不能改变 this 的指向,且不报错。

箭头函数不能使用 arguments、super、new.target

function foo() {setTimeout(() => {console.log('args:', arguments);
  }, 100);
}

foo(2, 4, 6, 8)
// args: [2, 4, 6, 8]

由于定时器的回调函数是一个箭头函数,所以其 this 指向上一层的 foo 函数的环境中的值。

在 es6 中可以使用 rest 参数代替 arguments 来访问函数的参数列表

let func = (...args) => {console.log(args);
}

func(1, 2, 3, 4, 5);
//[1,2,3,4,5]

没有原型

由于箭头函数没有自己的 this,, 所以箭头函数没有自己的原型。

let sayHi = () => {console.log('Hello World !')
};
console.log(sayHi.prototype); // undefined

不能作为事件的回调

在 js 中,事件的回调函数中,this 会动态的指向监听的对象,但是由于监听是一个全局函数,所以箭头函数的回调中 this 指向 window。

var button = document.getElementById('press');
button.addEventListener('click', () => {this.innerHtml = 'hello'});

在全局上下文下定义的箭头函数执行时 this 会指向 window,当单击事件发生时,浏览器会尝试用 button 作为上下文来执行事件回调函数,但是箭头函数预定义的上下文是不能被修改的,这样 this.innerHTML 就等价于 window.innerHTML,而后者是没有任何意义的。

正文完
 0

ES6箭头函数

79次阅读

共计 1412 个字符,预计需要花费 4 分钟才能阅读完成。

语法:
([param] [, param]) => {
statements
}

param => expression

使用:
()=>{···};// 零个参数用()表示
x =>{···};// 一个参数,可以省略()
(x,y)=>{···};// 多个参数不能省略()

** 多行语句需要用 {} 括起来,单行表达式不需要{},并且会作为函数返回值。**

特性:
箭头函数内部没有 constructor 方法,也没有 prototype,所以不支持 new 操作。但是它对 this 的处理与一般的普通函数不一样。箭头函数的 this 始终指向函数定义时的 this,而非执行时。
例如:
var o = {
x : 1,
fn : function() { console.log(this.x) },
test : function() {
setTimeout(function() {
this.fn();
}, 100);
}
};

o.test(); // TypeError : this.fn is not a function

上面的代码会出现错误,因为 this 的指向从 o 变为了全局(函数调用中的 this 都是指向全局的)。
要修改上面的代码如下:
var o = {
x : 1,
fn : function() { console.log(this.x) },
test : function() {
var _this = this;
setTimeout(function() {
_this.fn();
}, 100);
}
};
o.test();

通过使用外部事先保存的 this 就行了。
利用到箭头函数修改,箭头函数的 this 始终指向函数定义时的 this,而非执行时。
var o = {
x : 1,
fn : function() { console.log(this.x) },
test : function() {
setTimeout(() => { this.fn() }, 100);
}
};

o.test();

这回 this 就指向 o 了。箭头函数可以让 setTimeout 里面的 this,绑定定义时所在的作用域,而不是指向运行时所在的作用域。
上面代码中,转换后的 ES5 版本清楚地说明了,箭头函数里面根本没有自己的 this,而是引用外层的 this。
需要注意一点的就是箭头函数中的 this 是不会改变指向对象的,我们知道 call 和 apply 可以改变 this 的指向,但是在箭头函数中是无效的。
var x = 1,
o = {
x : 10,
test : () => {
console.log(this);//window 函数调用中的 this 都是指向全局的
return this.x
}
};
console.log(o.test()); // 1
console.log(o.test.call(o)); // 依然是 1

如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用 return 语句返回。
var sum = (num1, num2) => {return num1 + num2;}

由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号。var getTempItem = id => ({id: id, name: “Temp”});
使用注意点

函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象
不可以当作构造函数,也就是说,不可以使用 new 命令,否则会抛出一个错误。
不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 Rest 参数代替。
不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数。

正文完
 0