function Dog(name) {
this.name = name
}
// 共用的屬性或方法
Dog.prototype.species = '貓科'
let dog1 = new Dog('dog1')
let dog2 = new Dog('dog2')
console.log(dog1.species)
console.log(dog2.species)
// 是否指向同一個記憶體位置
console.log(dog1.species === dog2.species) // true
// 判斷constructor和instance的關係
console.log('isPrototypeOf', Dog.prototype.isPrototypeOf(dog1)) // true
// 判斷某一個屬性是不是本地屬性
console.log('hasOwnProperty', dog1.hasOwnProperty('species')) // false
// 遍遞所有的property
for (let prop in dog1) {
// prop是string
console.log(`dog1[${prop}]=`, dog1[prop])
}
重點 : 如果使用建構函數,__prop__(prototype)中一定會有一個constructor,且對應正確的建構函數
function Animal() {
this.species = '動物'
}
function Cat(name, color) {
this.name = name
this.color = color
}
// 指向並繼承Animal instance
Cat.prototype = new Animal()
// ㄧ定要加上這段,不然建構子會找不到建構函數
Cat.prototype.constructor = Cat
let cat1 = new Cat('大毛', '黄色')
// 結果
// Cat {name: "大毛", color: "黄色"}
// color: "黄色"
// name: "大毛"
// __proto__: Animal
// constructor: ƒ Cat(name,color)
// species: "动物"
// __proto__:
// constructor: ƒ Animal()
// __proto__: Object
function Animal() {}
Animal.prototype.species = '动物'
// 重要 : 現在的Animal prop和Cat prop都指向記憶體的同一個位置
// 如: Cat.prototype.species = '貓科',Animal.prototype.species也被改為'貓科'
Cat.prototype = Animal.prototype
// Animal的constructor也被指向Cat的Constructor
Cat.prototype.constructor = Cat
function Animal() {}
Animal.prototype.species = '动物'
function extend(Child, Parent) {
let F = function() {}
F.prototype = Parent.prototype
Child.prototype = new F()
Child.prototype.constructor = Child
}
extend.call(null, Cat, Animal)
把父類別的所有屬性和方法,拷貝至子類別
function Animal() {}
Animal.prototype.species = '动物'
function extend2(Child, Parent) {
var p = Parent.prototype
var c = Child.prototype
for (var i in p) {
c[i] = p[i]
}
}
extend.call(null, Cat, Animal)
var cat1 = new Cat('大毛', '黄色')
console.log(cat1.species) // 動物
把父物件的属性,全部拷貝给子物件
function extendCopy(p) {
var c = {}
for (var i in p) {
c[i] = p[i]
}
return c
}
var Doctor = extendCopy(Chinese)
// 但改Doctor會去影響Chinese
和另一物件不共用記憶體
var Chinese = {
nation: '中国'
}
var Doctor = {
career: '医生'
}
function object(o) {
function F() {}
F.prototype = o
return new F()
}
var Doctor = object(Chinese)
// 結果
// F {}
// __proto__:
// nation: "中国"
// __proto__: Object
var Chinese = {
nation: '中国'
}
var Doctor = {
career: '医生'
}
/**
* 深拷貝
* @param {Object} parent 父物件
* @param {Object} child 子物件
* @returns
*/
function deepCopy(parent, child) {
var parent = parent || {}
// 一開始 i為key name
for (var i in parent) {
// typeof string = string,typeof array = object
if (typeof parent[i] === 'object') {
child[i] = parent[i].constructor === Array ? [] : {}
// 進去後的parent為array或object,child為產生新物件的屬性
// 最後把結果丟回給child[property name]
deepCopy(parent[i], child[i])
} else {
child[i] = parent[i]
}
}
return child
}
Chinese.birthPlaces = ['北京', '上海', '香港']
var Doctor = deepCopy(Chinese)
// Doctor.birthPlaces.push('厦门')不會去影響Chinese.birthPlaces