javascript this指向
2020-12-18 10:34
标签:全局 efi 嵌套 赋值 cal reac 内置函数 参数 直接 在一些笔试题和项目中经常会出现一些this指向的问题。特此记录一下 this的默认指向 6.隐式绑定 7.隐式丢失 一、隐式丢失:函数别名 二、参数传递 三、内置函数 四、间接调用 五、其他情况 8.显示绑定
三、 数组的forEach(fn,对象) //map() filter() some() every()第二个参数改变this指向 10.严格模式下this指向 javascript this指向 标签:全局 efi 嵌套 赋值 cal reac 内置函数 参数 直接 原文地址:https://www.cnblogs.com/gengzhen/p/14088371.htmlconsole.log(this) //window
function fn1(){
console.log(this); //window
}
fn1() //fn1() === window.fn1(),所以指向了window
var a = 1;
var obj = {
a:2,
foo:function(){
// 函数当作对象的方法来调用时候,this指向obj
var a = 3;
var that = this;
console.log(that.a) //2
function test(){
console.log(this.a); //1
}
test()
}
}
obj.foo() //独立函数调用指向window
var a = 10;
var obj = {
a:2,
foo:function(){
console.log(this); //函数当作对象的方法来调用时候,this指向obj
(function test(){
console.log(this.a);
})() //自执行函数默认指向window,跟函数内部调用一致
}
}
obj.foo() // 10
var a = 10;
var obj = {
a:2,
foo:function(){
console.log(this); //函数当作对象的方法来调用时候,this指向obj
(function test(that){
console.log(that.a);
})(this) //自执行函数默认指向window,跟函数内部调用一致
}
}
obj.foo() // 10
var a = 0;
var obj = {
a:2,
foo:function(){
return function test(){
return this.a //闭包 :this默认指向了window
}
}
}
var bb = obj.foo()
console.log(bb()) //0
//当函数当作方法来调用,this指向了直接对象
function foo(){
console.log(this.a)
}
var obj = {
a:1,
foo:foo,
obj2:{
a:2,
foo:foo
}
}
// foo()函数的直接对象是obj,this的指向指向了直接对象
obj.foo(); //1
obj.obj2.foo(); //2
var a = 0;
function foo(){
console.log(this.a)
}
var obj = {
a:1,
foo:foo
}
// 把obj.foo()赋值给别名bar,造成隐式丢失的情况,因为只是把obj.foo()赋值了给了bar变量,而bar与obj对象毫无关系
var bar = obj.foo;
bar(); //0
相当于
var a = 0;
var bar = function foo(){
console.log(this.a)
}
bar()
// 2.参数传递
var a = 0;
function foo(){
console.log(this.a)
}
function bar(fn){
fn()
}
var obj = {
a:1,
foo:foo
}
// 把obj.foo当作参数传递到bar函数中,有隐式的函数复制fn = obj.foo, 只是把foo函数赋值给了fn,而fn与obj对象毫无关系,所以当前foo函数内部的this指向了window
bar(obj.foo) //0
等价于
var a = 0;
function bar(fn){
fn()
}
bar(function foo(){
console.log(this.a);
})
// 3.内置函数 setTimeout()和setInterval()第一个参数的回调函数中的this默认指向了window,跟第二种情况是类似
var a = 0;
function foo(){
console.log(this.a)
}
var obj = {
a:1,
foo:foo
}
setTimeout(obj.foo,1000) //0 window
// 4。间接调用
function foo(){
console.log(this.a)
}
var a = 0;
var obj = {
a:1,
foo:foo
}
var p = {a:4}
// obj.foo(); //1
// // 立即调用
// // 将obj.foo函数对象赋值给p.foo函数,然后立即执行。相当与仅仅是foo()函数的立即调用,内部的this默认指向了window
// (p.foo = obj.foo)() //0
p.foo = obj.foo
// 将obj.foo赋值给p.foo函数,之后p.foo()函数再执行,其实是属于p对象的函数的指向,this指向当前的p对象
p.foo() //4
//5.其他情况(指向了window的特殊情况)
function foo(){
console.log(this.a)
}
var a = 0;
var obj = {
a:1,
foo:foo
}
// 都是立即执行函数,指向window
(obj.foo = obj.foo)() //0
(false || obj.foo)() //0
(1,obj.foo)() //0
// call() apply() bind() 把对象绑定到this上,叫做显示绑定
var a = 0;
function foo(){
console.log(this.a);
}
var obj = {
a:2
}
foo() //0 window.foo()
foo.call(obj) //2
foo.apply(obj) //2
var fn = foo.bind(obj) //2
fn()
var a = 0;
function foo(){
console.log(this.a);
}
var obj = {
a:2
}
var bar = function(){
foo.call(obj)
}
setTimeout(bar,2000) //2
bar.call(window) //2
// 数组的forEach(fn,对象) //map() filter() some() every()第二个参数改变this指向
var id = ‘window‘;
var obj = {
id:‘fn‘
}
var arr = [1,2,3]
arr.forEach(function(el,index){
console.log(el,index,this);
},obj)
function Fn() {
//如果是new关键来执行函数,相当于构造函数来实例化对象,那么内部的this指向了当前实例化的对象
console.log(this); //Fn {}
}
var fn = new Fn()
console.log(fn); //Fn {}
function Fn2(){
// this还是指向了当前的对象
console.log(this);
// 使用return关键来返回对象的时候,实例化出来的对象是当前的返回对象
return {
name:‘zhen‘
}
}
var fn2 =new Fn2() //Fn2 {}
console.log(fn2) // {name: "zhen"}
var Person ={
fav:function(){
return this
}
}
var p = new Person.fav();
console.log(p); //fav {}
console.log(p===Person.fav); //false
// 实例化出来的对象内部的属性constructor属性指向了当前的构造函数
console.log(p.__proto__.constructor === Person.fav);
//1.独立调用的函数内部的this指向了undefined
function fn(){
‘use strict‘
console.log(this);
}
fn() //undefined
//2.严格模式下,函数apply()和call()内部this始终是他们的第一个参数
var color = ‘red‘;
function showColor(){
‘use strict‘
console.log(this.color);
}
showColor.call(undefined)