this的典型场景
注意: 函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,调用函数的那个对象
this是函数执行时在函数内部作用域创建的临时对象,只在当前函数执行过程中有效,代表持有当前函数的对象,其具有以下四种典型案例;
作为对象的方法调用。
构造器调用。
Function.prototype.call 或 Function.prototype.apply 调用。
作为普通函数调用。
- 对象内部函数类型属性值,此类函数执行时,this代表当前对象
var car = {
name:"didi",
say:function(){
console.log(this); //这里this代表当前对象
console.log(this.name); //这里返回didi
}
}
其扩展为(典型事件场景)
document.onclick = function(){ dom0级事件绑定
console.log(this) // 这里当点击时返回document
}
- 构造函数中this表示新对象
function Person(name.age){
this.name = name;
this.age = age;
}
var per = new Person("tom",28);
- call和apply中,this代表第一个参数,也就是要为函数扩充的作用域
var cup = {
size:"300ml",
price:"10$"
};
function showPrice(){
console.log(this.size);
console.log(this.price);
}
showPrice.call(cup); //这里函数调用对象,将对象cup中的参数赋值给函数,所以上方函数可以正常打印
以下扩充call和apply的典型案例
<div></div>
<div></div>
<div></div> //创建几个div
<div></div>
<script type="text/javascript">
var doms = document.getElementsByTagName("div"); // 提取节点并存入类数组doms中,其类似数组但是没有数组的方法
console.log(doms); //打印
var newDoms = Array.prototype.slice.call(doms,1,2); //这里用Array的原型调用call函数,将doms变成完全体的数组,然后调用slice截取下标从1开始到2为止的字符存入var newDoms中
// 使用call或者apply都可以为伪数组提供数组方式
- 普通函数之中,或者是其他场景,this都代表window
function fn(){
console.log(this);
}
fn();
//函数嵌套函数
function out(){
console.log(this); //这里的this返回的都是window
function inner(){
console.log(this);
}
inner();
}
out();
call,apply和bind
ECAMScript 3 给 Function 的原型定义了两个方法,它们是 Function.prototype.call 和 Function. prototype.apply。它们的作用一模
一样,区别仅在于传入参数形式的不同。
apply 接受两个参数,第一个参数指定了函数体内 this 对象的指向,第二个参数为一个带下 标的集合,这个集合可以为数组,也可以为类数组,apply 方法把这个集合中的元素作为参数传 递给被调用的函数:
var func = function( a, b, c ){
console.log ( [ a, b, c ] );
};
func.apply( null, [ 1, 2, 3 ] ); // 输出 [ 1, 2, 3 ]
call 传入的参数数量不固定,跟 apply 相同的是,第一个参数也是代表函数体内的 this 指向, 从第二个参数开始往后,每个参数被依次传入函数:
var func = function( a, b, c ){
console.log ( [ a, b, c ] );
};
func.call( null, 1, 2, 3 ); // 输出 [ 1, 2, 3 ]
当使用 call 或者 apply 的时候,如果我们传入的第一个参数为 null,函数体内的 this 会指 向默认的宿主对象,在浏览器中则是 window:
var func = function( a, b, c ){
console.log ( this === window );
}
func.apply( null, [ 1, 2, 3 ] ); // 输出 true
call和apply的用途
改变 this 指向
// 栗子1
var obj1 = {
name: 'obj1'
};
var obj2 = {
name: 'obj2'
};
window.name = 'window';
var getName = function(){
alert ( this.name );
};
};
getName();
getName.call(obj1)
getName.apply(obj2)
// 栗子2
// 如前文,可以稍作修改
document.getElementById("button").onclick = function() {
changeValue.call(this);
function changeValue() {
console.log(this.id) // button
}
};
借用其他对象的方法
(function(){
Array.prototype.push.call( arguments, 3 ); console.log ( arguments ); // 输出[1,2,3]
})( 1, 2 );
Function.prototype.bind
let obj = {
name: 'obj'
}
let getName = function() {
console.log(this.name)
}.bind(obj)
getName() // obj
网友评论