diveDylan / blog

My blog, detail is in the issues list
2 stars 0 forks source link

`prototype`以下两端代码各输出啥 (达达到家) #36

Open diveDylan opened 4 years ago

diveDylan commented 4 years ago
// case 1
function Person(name) {
    this.name = name
}
const a = new Person('dylan')
Person.prototype = {
     age: 10
}
console.log(a.age)

// case 2
function Person(name) {
     this.name = name
}
const a = new Person('dylan')
Person.prototype.age = 10
console.log(a.age)

依次输出undefined10

// stack progress

a { 
name: "dylan"
__proto__:
constructor: ƒ Person()
__proto__:
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
get __proto__: ƒ __proto__()
set __proto__: ƒ __proto__()
}

Person.prototype = {} 
// 将整个prototype斩断 a保持原有的原型,后续新的Person具有新的原型
// 可以这样理解,构造函数本质是函数, const a = new Person('dylan')
// 执行构造函数,赋值原型得到a, a的原型为一个引用地址
// Person.prototype = 赋值,可以理解为函数内部更改了整个原型赋值引用
// 而Person.prototype.age是在原引用上增加属性所以可以访问

理解了整个流程我们mock验证一下

let prot = {}
    function consTest (name) {
      this.name = name
      this.prot = prot
    }
    const c = new consTest('dylan')
    prot = { age: 10}
    const d = new consTest('d')
    console.log(c, d)

image

其实这题侧重的还是引用类型和函数执行的理解