JS的this指向

栏目: JavaScript · 发布时间: 5年前

内容简介:js函数中this是面试官最喜欢考察的,整理一下常用的this指向的知识点。非严格模式和严格模式中this都是指向顶层对象在非严格模式下,普通函数的this指向window

js函数中this是面试官最喜欢考察的,整理一下常用的this指向的知识点。

一、全局上下文

非严格模式和严格模式中this都是指向顶层对象

this.myname = 'xyf'
console.log(this) //Window {myname: 'xyf', …}

二、函数上下文

普通函数

在非严格模式下,普通函数的this指向window

{.line-numbers}
var myname = 'xyf'
var sayName = function(){
    console.log(this === window) // true
    console.log(this.myname) // 'xyf'
}
sayName()

这里的 sayName() 相当于调用了 window.sayName() 。在严格模式下,普通函数的this指向undefined

'use strict'
var myname = 'xyf'
var sayName = function(){
    console.log(this === window) // false
    console.log(this.myname) // 报错,因为this是undefined
}
sayName()

在ES5中,var会给顶层对象中(浏览器是window)添加属性,而使用let则不会。

let myname = 'xyf'
let sayName = function(){
    console.log(this === window) // true
    console.log(this.myname) // undefined
}
sayName()

对象中的函数

对象中的函数this指向对象本身

var myname = 'outside name'
var sayName = function(){
    console.log(this.myname)
}

var person = {
    myname: 'inside name',
    sayName: sayName,
    other: {
        myname: 'other name',
        sayName: sayName,
    }
}

person.sayName() // 'inside name'
person.other.sayName() // 'other name'

将对象中的函数赋值成变量,这样又变成普通函数,this指向顶层对象。

var newSayName = person.sayName;
newSayName() // 'outside name'

所以,通过上面我们可以看出来, 函数的定义位置不影响其this指向,this指向只和调用函数的对象有关

call、apply、bind改变this指向

通过call、apply、bind可以改变函数this的指向

语法:

fun.call(thisArg, arg1, arg2, ...)
fun.apply(thisArg, [arg1, arg2, ...])

thisArg是fun函数在运行时指定的this的值。但是指定的this值不一定就是该函数执行时真正的this值。如果这个函数处于非严格模式下,指定为null和undefined的this值会自动指向全局对象(windows中就是window对象);指定为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象;

var sayName = function(name1,name2){
    console.log(this, name1, name2) 
}

// Number {1} 'a' 'b'
sayName.call(1, 'a', 'b')

// Window { … } 'a' 'b'
sayName.call(null, 'a', 'b')

// Window { … } 'a' 'b'
sayName.call(undefined, 'a', 'b')

apply和call类似。只是参数不一样。它的参数是数组(或者类数组)。

sayName.apply(1, ['a', 'b'])

严格模式下,指向null和undefined的this值还是指向原来的。

var sayName = function(name1,name2){
    'use strict'
    console.log(this, name1, name2) 
}

sayName.call(null, 'a', 'b')
// null 'a' 'b'

bind和call和apply的调用方式相同,第一个值也是修改this的指向,只不过bind返回一个新的函数。

构造函数调用模式

function Dog(name){
    this.name = name;
    console.log(this)
}

var puppy = new Dog('apple')
// Dog {name: "apple"}

由此可知,new操作符调用时,this指向生成的新对象。

原型链中的调用模式

function Dog(name){
    this.name = name;
}

var puppy = new Dog('apple')
Dog.prototype.bark = function(){
    console.log(this, this.name)
}
puppy.bark()
//Dog {name: "apple"} "apple"

箭头函数调用模式

先看箭头函数和普通函数的重要区别:

  1. 没有自己的this、super、arguments和new.target绑定。
  2. 不能使用new来调用。
  3. 没有原型对象。
  4. 不可以改变this的绑定。
  5. 形参名称不能重复。

箭头函数中没有this绑定,必须通过查找作用域链来决定其值。 如果箭头函数被非箭头函数包含,则this绑定的是最近一层非箭头函数的this,否则this的值则被设置为全局对象。 比如:

var name = 'out'
var people = {
    name: 'xyf',
    sayName: function(){
        var arrowFun = () => {
            console.log(this.name)
        }
        arrowFun()
    },
    arrowSayName: () => {
        console.log(this.name)
    }
}
people.sayName()
people.arrowSayName()

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

An Introduction to Probability Theory and Its Applications

An Introduction to Probability Theory and Its Applications

William Feller / Wiley / 1991-1-1 / USD 120.00

Major changes in this edition include the substitution of probabilistic arguments for combinatorial artifices, and the addition of new sections on branching processes, Markov chains, and the De Moivre......一起来看看 《An Introduction to Probability Theory and Its Applications》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

MD5 加密
MD5 加密

MD5 加密工具