Object.defineProperty定义的属性在谷歌浏览器显示的问题

新手上路,请多包涵

1 代码如下

function Vue () {
    this._init()
}    

Vue.prototype._init = function () {
    let vm = this
}
Object.defineProperty(Vue.prototype, '$ssrContext', {
    get () {
        return false
    }
})

const vm = new Vue()

2 实例化后在浏览器查看到如下
图片描述

3 问题
同样在原型上定义的方法,使用Object.defineProperty方法,为什么在当前实例下就有一个$ssrContext属性,是否是浏览器实现原因?

阅读 2.9k
3 个回答

可以看一下 MDN 关于 get 的描述

关注这里有一句话

get 语法将对象属性绑定到查询该属性时将被调用的函数。

然后 new 一个实例的时候,这里其实有一些隐含操作
当函数 A 直接 return 一个对象的时候,b 的值就是 A return 出的对象,而且不会包含 A 的原型中的对象
因为 return 出的对象是一个新的对象,他与 A 的原型没有任何关系。

例如下面的代码:

function A () { return { age: 22 } }
A.prototype.test = 'hello'
var b = new A()
// b => { age: 22 }
// 这里 b.test 是访问不到的

但是如果没有显式的 return 一个对象,这时会创建一个新的对象,然后把当前函数(A)的 this 作用域绑定给这个对象,执行函数(A)中的代码,并访问了原型(*)这里结合上面 MDN 的那句描述,就可以看出多出的属性是为什么。

但是这里多出的属性有些怪异
例如下面的代码

function A () {}
A.prototype._init = function() { console.log('init') }
Object.defineProperty(A.prototype, 'test', {
    get() {
        console.log(this)
        return 24
    }
})

var b = new A()

A.prototype.hasOwnProperty('test')
// => true
A.prototype.hasOwnProperty('_init')
// => true

A.hasOwnProperty('test')
// => false

// 这里虽然看似 test 是 A 上的属性,但是并不显式的属于 A

图片描述

Vue.prototype._init

这种写法是在 Vue 的原型上定义方法,实例通过 proto 可访问到。

vm.__proto__ === Vue.prototype // true
Object.defineProperty(Vue.prototype, '$ssrContext', {
    get () {
        return false
    }
})

用 get 的时候回默认继承属性。

Object.defineProperty(Vue.prototype, '$ssrContext', {
    value: false
})

这样写就么有。

因为你是在原型链上创建的,实例化当然有了

推荐问题