function foo() {
console.log(this);
}
foo(); //全局变量
函数调用中的this也指向全局变量。
注:ECMAScript5的strict模式不存在全局变量,这里的this是undefined。
console.log(this); //全局变量
全局范围使用this指向的是全局变量,浏览器环境下就是window。
注:ECMAScript5的strict模式不存在全局变量,这里的this是undefined。
var test = {
foo: function () {
console.log(this);
}
}
test.foo(); //test对象
对象方法调用中,this指向调用者。
如果函数或者方法调用之前带有关键字new,它就构成构造函数调用。使用new来调用函数, 或者说发生构造函数调用时,会自动执行下面的操作。
function foo(x){
this.x = x;
console.log(this); // foo {x: 2}
}
var f = new foo(2);
console.log(f.x); // 2
使用new来调用foo()时, 会构造一个新对象并把它绑定到foo()调用中的this上。即构造函数的this指向它实例化出来的对象。
function foo(a, b) {
console.log(this);
}
var bar = {};
foo.apply(bar, [1, 2]); //bar
foo.call(1, 2); //Number对象
使用Function.prototype的call或者apply方法是,函数内部this会被设置为传入的第一个参数。call与apply后面如果是undefined和null,this指向的是window
<input type="button" value="点我">
<script>
document.querySelector("input").onclick = function(){
console.log(this); //指向当前按钮
};
</script>
在ECMAScript中,每个函数都包含两个继承而来的方法:apply() 和 call(),这两个方法的用途都是在特定的作用域中调用函数,主要作用跟bind一样,用来改变函数体内this的指向,或者说是在函数调用时改变上下文。
apply() 和 call(), 这两个方法的用途都是在特定的作用域中调用函数,主要作用跟 bind 一样,用来改变函数体内 this 的指向,或者说是在函数调用时改变上下文。
我们可以运用这个特性实现借用别的函数实现自己的功能如下代码:
function Person(name, age, sex) {
this. name = name;
this.age = age;
this.sex = sex;
}
function Student ( name, age, sex, tel, grade) {
// Person.call(this,name, age ,sex) ;
Person.apply(this,[name, age ,sex]) ;
this.tel = tel;
this.grade = grade;
}
var student = new Student( 'sunny', 123, 'male', 139, 2017)
console.log(student.name)//sunny
我们可以看出来,原本Student构造函数中是没有name属性的,我们call和apply都是为了动态改变 this 而出现的,
再来个常见的使用例子:数组没有max方法,可以使用Math对象上的max方法
const arr =[1,2,3,4,5]
const max = Math.max.apply(null,arr)
console.log(max)//5
call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
fun.call(thisArg,arg1,arg,…)
fun.apply(thisArg,[argsArray])
fun.bind(thisArg,arg1,arg2,…).
const obj= {}
function test(..args) {
console.log(args);
const newFn = test.bind(obj, 1,2);
newFn(3,4);
// [1,2,3,4]
直接看看三者之间的关系吧
//先来一个对象big吧
var big = {
name:'BaBa',
saying:function (age){
console.log(this.name,'age:',age);
}
};
//再来一个small对象
var small= {
name:'ErZi'
};
//如果想调用big的saying方法来说出‘Erzi’:
//使用bind方法
big.saying.bind(small)(20);//打印结果为ErZi age: 20
//使用call方法
big.saying.call(small,20);//打印结果为ErZi age: 20
//使用apply方法
big.saying.apply(small,[20]);//打印结果为ErZi age: 20
1. 使用场景
2. 相同点
都是用来改变this指向
3. 不同点
//bind方法
//1、bind方法放在函数的原型中
// -->fn.__proto__===fn的构造函数.prototype
// -->所有的函数对象的构造函数是Function
// -->Function 创建了Function
// -->Function 创建了Object
// -->Function 创建了fn
Function.prototype._bind=function(target){
//这里的this其实fn
//target表示新函数的内部的this的值
//利用闭包创建一个内部函数,返回那个所谓的新函数
return ()=>{
//执行fn里面的逻辑
this.call(target); //this.apply(target)
}
// //等价于:
// var _that=this;
// return function(){
// _that.call(target);
// }
}
function fn(){
console.log(this);
}
var _f1=fn.bind({age:18})