call
let fn = function(a,b){
console.log(this,a,b);
}
let obj = {name:"obj"};
fn.call()通过在原型链上查找到function.prototype.call方法然后执行
执行方式:
fn.call(【this】,param...)
首先将this的指向改变为第一个参数[this],然后获取后面的参数param传给函数fn执行
apply
apply和call的区别在于传递给函数的参数方式不同,将其转为数组的方式
比如:
fn.call(obj,1,2)
fn.apply(obj,[1,2])
bind
bind使用方法和call一样,区别在于call是立即执行,而bind仅仅是绑定并不执行函数
比如:
fn.call(obj,1,2)会直接输出
fn.bind(obj,1,2)则输出
说明了call方法会直接执行函数fn里的内容,而bind方法需要例如点击事件来触发函数
拓展一:严格模式和非严格模式
严格模式:禁止使用with语句、所有变量都要先声明在使用、函数中的this是undefined、call中第一个参数是谁,this就指向谁,包括null和undefined,如果不传参数this就是undefined
非严格模式:可以使用with语句、未声明的变量会自动设为全局变量、this是全局对象、call中如果不传参数,或者第一个参数是null或nudefined,this都指向window
拓展二:with语句
with 语句可以方便地用来引用某个特定对象中已有的属性,但是不能用来给对象添加属性。要给对象创建新的属性,必须明确地引用该对象。
比如:
function Lakers() {
this.name = "kobe bryant";
this.age = "28";
this.gender = "boy";
}
var people=new Lakers();
with(people)
{
var str = "姓名: " + name + "<br>";
str += "年龄:" + age + "<br>";
str += "性别:" + gender;
document.write(str);
}
拓展三:monkey-patching
猴子补丁(monkey patching)
在运行时动态修改模块、类或函数,通常是添加功能或修正缺陷。猴子补丁在代码运行时(内存中)发挥作用,不会修改源码,因此只对当前运行的程序实例有效。 因为猴子补丁破坏了封装,而且容易导致程序与补丁代码的实现细节紧密耦合, 所以被视为临时的变通方案,不是集成代码的推荐方式。
在猴子补丁中使用apply动态修改方法:
function trace(o,m){
var ori=o.m;//在闭包中保存原始方法
o[m]=function(){//定义新的方法
console.log(new Date(),'Entering:',m);
var result=ori.apply(this,arguments);
console.log(new Date(),'Exiting',m);
return result;
};
}
拓展四:arguments参数
在函数调用时,浏览器都会传进两个参数,一个是调用上下文的this对象,另一个就是封装实参的arguments对象
通过例子来看:
function fun(){
console.log(arguments);
}
fun('tom',[1,2,3],{name:'Janny'});
控制台输出:
可以看到除了我们传递进去的参数以外,还有一个指向函数的callee参数,一个参数数组的长度length,还有个Symbol
Symbol指向一个values函数,是有关ES6中迭代器的知识
拓展五:改变this指向的方法
已知上面的call、apply、bind方法
除此之外还有:
var一个变量保存this指向
ES6中的箭头函数:
console.log(this) // window
let fun = () => {
console.log(this)
}
box.onclick = fun // this 指向 window
box.onclick = function(){
let fun = () => {
console.log(this) // this 指向 box
}
console.log(this) // this 指向 box
fun()
}
// 普通匿名函数
box.onclick = function(){
let fun = function () {
console.log(this) // this 指向window
}
console.log(this) // this 指向 box
fun()
}