this 常见指向问题
this 的用法
1. 直接在函数中使用 谁调用这个函数 this 就指向谁
2. 对象中使用, 一般情况下指向该对象
3. 在构造函数中使用
改变 this 的指向, 两种方法的作用都是相同的, 传递的写法不同而已.
call -- (指向谁, 参数 1, 参数 2......)
apply -- (指向谁,[参数 1, 参数 2]) 数组的形式
1. this 与普通函数执行
当一个函数执行不带任何修饰时, 使用默认绑定规则.
默认绑定: 函数体如果在非严格模式下, this 绑定到 Windows, 严格模式下绑定到 undefined.
- // 1.1 函数体在非严格模式下的全局函数执行
- function fn () {
- console.log(this)
- }
- fn1() // => Windows
- // 1.2 函数体在严格模式下的全局函数执行
- 'use strict'
- function fn () {
- console.log(this)
- }
- fn() // => undefined
- // 1.3 函数体在非严格模式下的函数中的函数执行
- function fn1 () {
- function fn2 () {
- console.log(this)
- }
- fn2()
- }
- fn1() // => Windows
- // 1.4 函数体在严格模式下的函数中的函数执行
- 'use strict'
- function fn1 () {
- function fn2 () {
- console.log(this)
- }
- fn2()
- }
- fn1() // => undefined
- // 1.5 函数体在非严格模式下, 而函数调用在严格模式下时, this 依然指向 Windows
- function fn () {
- console.log(this)
- }
- (function () {
- 'use strict'
- fn() // => Windows
- })()
2. this 与对象中的方法执行
2.1 无论是否是严格模式, 当函数引用有上下文对象时, 隐式绑定规则会把函数调用中的 this 绑定到这个上下文对象.
- // 2.1.1 函数直接在对象中声明
- var obj = {
- a: 1,
- test: function () {
- console.log(this.a)
- }
- }
- obj.test(); // => 1
- // 2.1.2 函数先声明, 再由对象引用
- function test () {
- console.log(this.a)
- }
- var obj = {
- a: 1,
- test: test
- }
- obj.test(); // => 1
2.2 对象属性引用链中只有最顶层或者说只有最后一层会影响调用位置
- // 2.2.1 多层对象引用, this 指向离函数调用最近的对象
- function test () {
- console.log(this.a)
- }
- var obj2 = {
- a: 2,
- test: test
- }
- var obj1 = {
- a: 1,
- obj2: obj2
- }
- obj1.obj2.test() // => 2
2.3 隐式丢失: 被隐式绑定的函数可能会丢失绑定对象.
- // 2.3.1 将 obj.foo 当作函数别名赋值给一个变量
- function foo () {
- console.log(this.a)
- }
- var obj = {
- a: 2,
- foo: foo
- }
- var bar = obj.foo // 函数别名
- var a = '全局属性'
- bar() // => 全局属性
在 2.3.1 中, 虽然 bar 是 obj.foo 的一个引用, 但是实际上, 它引用的是 foo 函数本身, 因此此时的 bar() 其实是一个不带任何修饰的普通函数调用. 因此也使用默认绑定规则.
- // 2.3.2 将 obj.foo 当作 bar 的回调函数.
- function foo () {
- console.log(this.a)
- }
- function bar (fn) {
- fn()
- }
- var obj = {
- a: 2,
- foo: foo
- }
- var a = '全局属性'
- bar(obj.foo) // => 全局属性
3.this 与 call,apply
显示绑定规则: this 指向第一个参数.
- 3.1 call
- // 3.1.1
- var xw = {
- name : "小王",
- gender : "男",
- age : 24,
- say : function(school,grade) {
- console.log(this.name + "," + this.gender + ", 今年" + this.age + ", 在" + school + "上" + grade);
- }
- }
- var xh = {
- name : "小红",
- gender : "女",
- age : 12
- }
- xw.say.call(xh, "实验小学", "六年级") // => 小红 , 女 , 今年 12 , 在实验小学上六年级
在 3.1.1 代码示例中, 当调用 say 时强制把它的 this 绑定到了 xh 上.
- 3.2 apply
- // 3.2.1
- var xw = {
- name : "小王",
- gender : "男",
- age : 24,
- say : function(school,grade) {
- console.log(this.name + "," + this.gender + ", 今年" + this.age + ", 在" + school + "上" + grade);
- }
- }
- var xh = {
- name : "小红",
- gender : "女",
- age : 12
- }
- xw.say.apply(xh,["实验小学","六年级"]) // => 小红 , 女 , 今年 12 , 在实验小学上六年级
来源: http://www.bubuko.com/infodetail-2890808.html