共计 3077 个字符,预计需要花费 8 分钟才能阅读完成。
箭头函数
es6 容许应用“箭头”(=>)定义函数。岂但简化了代码,最重要的一点就是解决了 es5 中的 this 指向问题, 在 es6 中的箭头函数里 this 指向的永远是定义时的对象,而非应用时的对象。例如:
let f = v => v;
// 等同于
let f = function (v) {return v;};
如果箭头函数不须要参数或须要多个参数,就应用一个圆括号代表参数局部。例如:
let f = () => 5;
// 等同于
let f = function () { return 5};
let sum = (num1, num2) => num1 + num2;
// 等同于
let sum = function(num1, num2) {return num1 + num2;};
如果箭头函数的代码块局部多于一条语句,就要应用大括号将它们括起来,并且应用 return 语句返回。例如:
let sum = (num1, num2) => {return num1 + num2;}
箭头函数使得表白更加简洁。例如:
const isEven = n => n % 2 == 0;
const square = n => n \* n;
下面代码只用了两行,就定义了两个简略的工具函数。如果不必箭头函数,可能就要占用多行,而且还不如当初这样写醒目。
箭头函数的一个用途是简化回调函数。
// 失常函数写法
[1,2,3].map(function (x) {return x * x;});
// 箭头函数写法
[1,2,3].map(x => x * x);
// 失常函数写法
var result = values.sort(function (a, b) {return a - b;});
// 箭头函数写法
var result = values.sort((a, b) => a - b);
箭头函数有几个应用留神点。
(1)函数体内的 this 对象,就是定义时所在的对象,而不是应用时所在的对象。
(2)不能够当作构造函数,也就是说,不能够应用 new 命令,否则会抛出一个谬误。
(3)不能够应用 arguments 对象,该对象在函数体内不存在。
例如:
let handler = {
id: '123456',
init: function() {document.addEventListener('click',event => this.doSomething(event.type), false);
},
doSomething: function(type) {console.log('Handling' + type + 'for' + this.id);
}
};
下面代码的 init 办法中,如果用是是一般的 function 函数,this 本该是 document 自身,应用了箭头函数后,使这个箭头函数外面的 this,总是指向 handler 对象;
doSomething 里的 this 指向的是 doSomething 运行时所在的对象 handler。
this 关键字
this 能够用在构造函数之中,示意实例对象。除此之外,this 还能够用在别的场合。但不论是什么场合,this 都有一个共同点:它总是返回一个对象,简略说,this 就是属性或办法“以后”所在的对象。
this 次要有以下几个应用场合
(1)全局环境
全局环境应用 this,它指的就是顶层对象 window。
this === window // true
function f() {console.log(this === window);
}
f() // true
留神:严格模式下 一般函数外部 this 等于 undefined
(2)构造函数
构造函数中的 this,指的是实例对象
function Person(p) {
this.p = p;
console.log(this)//Person {p: "测试 this 指向"}
};
var obj = new Person()
从打印后果能够看出下面代码里的 this 指向的就是 Person 实例
(3)对象的办法
如果对象的办法外面蕴含 this,this 的指向就是办法运行时所在的对象。
var person = {
name: '张三',
describe: function () {return '姓名:'+ this.name;}
};
person.describe()// "姓名:张三"
下面代码中,this.name 示意 name 属性所在的那个对象。因为 this.name 是在 describe 办法中调用,而 describe 办法所在的以后对象是 person,因而 this 指向 person,this.name 就是 person.name。
(4)匿名函数中的 this
在办法外部呈现匿名函数,那么匿名函数里的 this 指向的对象是不确定的, 例如:
var dogs={
name:"小黑",
age:"1 岁",
voice:function(){console.log(this.name);
setTimeout(function(){console.log(this);// 返回的是 window
console.log(this.name);// 没有返回值,因为这里的 name 是一个不存在的属性
// 解决办法是 console.log(dogs.name);
},1000);
}
}
dogs.voice();
扭转 this 指向
1. 应用箭头函数
2. 函数里,如果想在办法里的事件外部调用这个办法内部的办法,能够在内部申明一个变量,let that=this;
例如:
function a(){
let that=this;
function b(){console.log(that)
}
b();}
3. 应用 bind 或者、call、或者 apply 办法扭转 this 指向;
bind 是 es6 的办法,扭转的是新函数的 this;
call 和 apply 是 es5 的办法:
call 扭转的是原函数的 this, 它的第一个参数是扭转的 this 指向的对象,残余的参数顺次赋值给原函数形参;
apply 扭转的也是原函数的 this, 它的第一个参数也是扭转的 this 指向的对象,第二个参数是一个数组,数组里的值顺次赋值给原函数的形参
例如:
// 在全局申明一个 box 函数,应用 bind 办法将 this 指向从 window 变为 box
function box(){console.log(this);//[object global]
}
box();
let res=box.bind(box);
res();
//bind: 绑定数组
function box2(a,b){console.log(this);//1,2
}
let arr=[1,2];
let res2=box2.bind(arr);
res2(...arr);
//bind: 绑定对象
function objs(o){console.log(this);//{o: '对象'}
}
let obj={o:"对象"};
let res3=objs.bind(obj);
res3(obj.o);
//es5:call
function box4(aa,bb){console.log(this);//[1111]
}
let ccc=[1111];
box4.call(ccc,10,12);
//es5:apply
function box5(cc,dd){console.log(this);//{a:"你好"}
}
var obj={a:"你好"};
box5.apply(obj,[88,99]);
//apply 的 max 和 min 办法
// 如果第一个参数为空示意不扭转原对象
var arr2=[5,7,10,11,345,365];
console.log(Math.max.apply(null,arr2));//365
console.log(Math.min.apply(null,arr2));//5