每日JavaScript - 19 (this,js内存引用)

看到一道关于this的题目,挺简单的
https://juejin.im/post/5bfe8fc5e51d4514e0515b90#comment

var num = 1;
var myObject = {
    num: 2,
    add: function() {
        this.num = 3;
        (function() {
            console.log(this.num);
            this.num = 4;
        })();
        console.log(this.num);
    },
    sub: function() {
        console.log(this.num)
    }
}
myObject.add();
console.log(myObject.num);
console.log(num);
var sub = myObject.sub;
sub();

哈哈,第一次看的时候少看第一句,输出了undefined。做做看嘛,输出一下就会了。
记住两点: this是在函数调用时才确定。this的指向要看上下文(有没有被那个对象拥有,没被拥有,this指向undefined,非严格模式指向全局对象)
哈哈,this就是如此简单。

今天被一道看似简单的题难住

var a = {n: 1};
var b = a;
a.x = a = {n: 2};

console.log(a.x);
console.log(b.x);

两个输出分别是什么呢?
我觉得我会解释不清,先上文章。
https://juejin.im/post/5bf6095f6fb9a049f9123492#heading-11

var b = a;

所有的引用类型都保存在堆内存中,所以{n: 1}保存在堆中。a拥有{n: 1}的内存地址(指针?),而这句话就是b也copy了{n: 1}的内存地址,注意不是copy了a的内存地址,a和b都在栈内存中。

a.x = a = {n: 2};

这句话做了什么?
首先,.运算符优先于=运算符,优先运行a.x,使得在堆内存中的{n: 1},变成{n: 1, x: undefined}。
然后,进行赋值运算,赋值运算是从右到左的,

a = {n: 2

这时a不再拥有原先堆内存的地址,拥有一个新的内存地址。

a.x = a

最后,a.x再copy了a的新内存地址。需要注意的是这时候a.x是第一步中的{n: 1, x: undefined}那个对象,其实就是b.x,相当于b.x = {n: 2}

我去看看作者推荐的文章再学习学习。

提示:
开发中不能用全局变量,因为JavaScript垃圾回收机制很难回收全局变量,还有全局变量很容易引发命名冲突。

更新两道this难题

/**
 * Question 1
 */

var name = 'window'

var person1 = {
  name: 'person1',
  show1: function () {
    console.log(this.name)
  },
  show2: () => console.log(this.name),
  show3: function () {
    return function () {
      console.log(this.name)
    }
  },
  show4: function () {
    return () => console.log(this.name)
  }
}
var person2 = { name: 'person2' }

// person1
person1.show1()
// peroson2
person1.show1.call(person2)

// window
person1.show2()
// window
person1.show2.call(person2)

// window
person1.show3()()
// person2
person1.show3().call(person2)
// window
person1.show3.call(person2)()

// person1
person1.show4()()
// person1
person1.show4().call(person2)
// person2
person1.show4.call(person2)()

/**
 * Question 2
 */
var name = 'window'

function Person (name) {
  this.name = name;
  this.show1 = function () {
    console.log(this.name)
  }
  this.show2 = () => console.log(this.name)
  this.show3 = function () {
    return function () {
      console.log(this.name)
    }
  }
  this.show4 = function () {
    return () => console.log(this.name)
  }
}

var personA = new Person('personA')
var personB = new Person('personB')

// personA
personA.show1()
// personB
personA.show1.call(personB)

// personA
personA.show2()
// personA
personA.show2.call(personB)

// window
personA.show3()()
// personB
personA.show3().call(personB)
// personB
personA.show3.call(personB)()

// personA
personA.show4()()
// personA
personA.show4().call(personB)
// personB
personA.show4.call(personB)()

这里我做了两遍只有部分对的,看了文章没记答案再做全队了。其中思路不是很清晰,请大家阅读
https://juejin.im/post/5c00d62df265da614c4c86f8#comment
https://juejin.im/post/59aa71d56fb9a0248d24fae3#comment
值得注意的是:(MDN原话)
箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this
鉴于 this 是词法层面上的,严格模式中与 this 相关的规则都将被忽略。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值