1.在Javascript中,this指向函数执行时的当前对象
function foo ( ) {
console. log ( this . a ) ;
}
function doFoo ( ) {
foo ( ) ;
}
该处的执行foo()的时候,执行环境为doFoo函数,而该函数为普通函数,this指向window
2.箭头函数时不绑定this的,它的this来自原其父级所处的上下文
var a = 10
var obj = {
a : 20 ,
say : ( ) => {
console. log ( this . a)
}
}
obj. say ( )
var anotherObj = { a : 30 }
obj. say . apply ( anotherObj)
该代码的obj对象是在全局定义的,故箭头函数say()方法继承其父级所处的上下文,即windows,所以第一个输出仍然是10,后面虽然让say方法指向了另外一个对象,但是仍不能改变箭头函数的特性,它的this仍然是指向全局的,所以依旧会输出10。 若为say为普通函数,其this指向指向他所在的对象,即输出obj其中的a的值
3.如果call第一个参数传入的对象调用者是null或者undefined,call方法将把全局对象(浏览器上是window对象)作为this的值
function a ( ) {
console. log ( this ) ;
}
a . call ( null ) ;
输出window对象 但若开启了严格模式,null 就是 null,undefined 就是 undefined
'use strict' ;
function a ( ) {
console. log ( this ) ;
}
a . call ( null ) ;
a . call ( undefined ) ;
var a = 10 ;
var obj = {
a : 20 ,
fn : function ( ) {
var a = 30 ;
console. log ( this . a)
}
}
obj. fn ( ) ;
obj. fn . call ( ) ;
( obj. fn) ( ) ;
obt.fn.call():
这里call的参数啥都没写,就表示null,我们知道如果call的参数为undefined或null,那么this就会指向全局对象this,所以会打印出 10;(obj.fn)()
:相当于立即执行 obj.fn()
4. 使用new构造函数时,其this指向的是全局环境window
var obj = {
name : 'cuggz' ,
fun : function ( ) {
console. log ( this . name) ;
}
}
obj. fun ( )
new obj. fun ( )
5. 对象不构成单独的作用域
var obj = {
say : function ( ) {
var f1 = ( ) => {
console. log ( "1111" , this ) ;
}
f1 ( ) ;
} ,
pro : {
getPro : ( ) => {
console. log ( this ) ;
}
}
}
var o = obj. say;
o ( ) ;
obj. say ( ) ;
obj. pro. getPro ( ) ;
调用o()
:注意此时调用的环境是在全局作用域下,f1()
箭头函数继承父级say function()
在全局作用域中,故打印出window; obj.say()
:谁调用say,say 的this就指向谁,所以此时this指向的是obj对象;obj.pro.getPro()
:由于getPro处于pro中,而对象不构成单独的作用域,所以箭头的函数的this就指向了全局作用域window;
6.立即执行函数调用this指向window,对象方法调用this指向该方法所属对象
var myObject = {
foo : "bar" ,
func : function ( ) {
var self = this ;
console. log ( this . foo) ;
console. log ( self. foo) ;
( function ( ) {
console. log ( this . foo) ;
console. log ( self. foo) ;
} ( ) ) ;
}
} ;
myObject. func ( ) ;
func
是由myObject
调用,this指向myObject
,故self
也指向myObject
立即执行匿名函数表达式的this指向window 。立即执行匿名函数的作用域处于myObject.func
的作用域中,在这个作用域找不到self变量,沿着作用域链向上查找self变量,找到了指向 myObject对象的self
7. 对象中若存在立即执行函数会直接执行后销毁
window. number = 2 ;
var obj = {
number : 3 ,
db1 : ( function ( ) {
console. log ( this ) ;
this . number *= 4 ;
return function ( ) {
console. log ( this ) ;
this . number *= 5 ;
}
} ) ( )
}
var db1 = obj. db1;
db1 ( ) ;
obj. db1 ( ) ;
console. log ( obj. number) ;
console. log ( window. number) ;
输出: 一开始在初始化obj对象时,立即执行函数this指向window,此时已经执行this.number *= 4
,window.number
为8 然后执行db1()
由于返回的是一个普通函数,在全局中调用,this指向window,故window.number
为8*5 = 40
function ( ) {
console. log ( this ) ;
this . number *= 5 ;
}
最后执行obj.db1()
,this指向obj对象,执行返回的函数,obj.number
为3*5 = 15
8.this的指向通常是调用函数的时候确定的,一般指向调用者
var length = 10 ;
function fn ( ) {
console. log ( this . length) ;
}
var obj = {
length : 5 ,
method : function ( fn ) {
fn ( ) ;
arguments[ 0 ] ( ) ;
}
} ;
obj. method ( fn, 1 ) ;
调用fn()
的时候在method方法中执行,对象不构成作用域,故this指向的是window,输出10 arguments[0]
为fn(),相当于arguments
调用方法,this指向arguments,而这里传了两个参数,故输出arguments长度为2
9. 注意对象中函数的写法,函数调用的时机
var a = 1 ;
function printA ( ) {
console. log ( this . a) ;
}
var obj= {
a : 2 ,
foo : printA,
bar : function ( ) {
printA ( ) ;
}
}
obj. foo ( ) ;
obj. bar ( ) ;
var foo = obj. foo;
foo ( ) ;
obj.foo(),
foo 的this指向obj对象,所以a会输出2;obj.bar(),
printA在bar方法中执行,所以此时printA的this指向的是window,所以会输出1;foo(),
foo是在全局对象中执行的,所以其this指向的是window,所以会输出1;
10.
var x = 3 ;
var y = 4 ;
var obj = {
x : 1 ,
y : 6 ,
getX : function ( ) {
var x = 5 ;
return function ( ) {
return this . x;
} ( ) ;
} ,
getY : function ( ) {
var y = 7 ;
return this . y;
}
}
console. log ( obj. getX ( ) )
console. log ( obj. getY ( ) )
匿名函数的this是指向全局对象的,所以this指向window,会打印出3; getY是由obj调用的,所以其this指向的是obj对象,会打印出6;
11.
function a ( xx ) {
this . x = xx;
return this
} ;
var x = a ( 5 ) ;
var y = a ( 6 ) ;
console. log ( x. x)
console. log ( y. x)
函数a是在全局作用域调用,所以函数内部的this指向window对象,故x的值为window,而window对象中没有x属性,所以会输出undefined 当执行y.x时,y为window,并会给全局变量中的x赋值为6,所以会打印出6
12.this绑定的优先级:new绑定 > 显式绑定 > 隐式绑定 > 默认绑定
function foo ( something ) {
this . a = something
}
var obj1 = {
foo : foo
}
var obj2 = { }
obj1. foo ( 2 ) ;
console. log ( obj1. a) ;
obj1. foo . call ( obj2, 3 ) ;
console. log ( obj2. a) ;
var bar = new obj1. foo ( 4 )
console. log ( obj1. a) ;
console. log ( bar. a) ;