天然,除了內置對象外,能夠經過JS代碼自定義對象。編程
下面分別看一下代碼示例:bash
function Phone(brand) {
this.brand = brand
}
let nokia = new Phone('Nokia')
console.log(nokia.constructor === Phone); // true
console.log(nokia.constructor.prototype === Phone.prototype); // true
console.log(Phone.prototype.__proto__ === Object.prototype); // true => the final relationship between Phone() and Object()
console.log('Object.prototype.__proto__: ', Object.prototype.__proto__); // null
function Smartphone(model) {
this.model = model
}
let iphone8 = new Smartphone('iphone8')
console.log(iphone8.constructor === Smartphone); // true
// prototype繼承
Smartphone.prototype = new Phone('Huawei')
let honor = new Smartphone('honor')
console.log(honor.constructor === Smartphone); // false
console.log(honor.constructor === Phone); // true
console.log(honor.brand); // Huawei => 繼承了brand屬性
console.log(honor.model); // honor
// 直接以字面量形式聲明時,至關於構造函數爲Object
let ironman = {name: 'Tony Stark'}
console.log(ironman.constructor === Object) // true
console.log(ironman.constructor.prototype === Object.prototype) // true
複製代碼
// 創建一個原型爲null的對象
let spiderman = Object.create(null, {
props: {
name: 'Peter Park'
}
});
console.log(spiderman.constructor); // => undefined
// 建立一個原型爲Array的對象
let array = Object.create(Array.prototype, {});
console.log(array.constructor); // => Array()
console.log(array.constructor.prototype); // => [constructor: ƒ, ...]
// 建立一個原型爲自定義類的對象
function Car() {
this.fix = function() {
console.log('going to fix');
}
}
let audi = Object.create(Car.prototype, {});
audi.ov = '3.0T'
Car.prototype.charge = function() {
console.log('going to charge');
}
console.log(audi.constructor); // Car()
console.log(audi.constructor.prototype); // {charge: ƒ, constructor: ƒ}
複製代碼
將某個類的prototype指向爲某個對象後,此類將會繼承該對象的全部實例成員,靜態成員除外。看例子:iphone
function Phone(brand) {
this.brand = brand
this.online = function() {
console.log(brand + ' is going to online');
}
}
let nokia = new Phone('Nokia')
console.log(nokia.__proto__ === nokia.constructor.prototype); // true => 對象的__proto__便是其構造器的prototype
console.log(nokia.constructor.prototype.__proto__ === Object.prototype); // true
console.log('prototype of nokia: ', nokia.prototype); // undefined => 可再次看出prototype是構造器層面的屬性,且__proto__是對象層面的屬性
nokia.online(); // Nokia is going to online
Phone.prototype.onMsg = function() {
console.log('nokia message coming');
}
nokia.onMsg(); // nokia message coming
function Smartphone(model) {
this.model = model
this.oncalling = function() {
console.log(model + ' is on calling');
}
}
let iphone8 = new Smartphone('iphone8')
iphone8.oncalling(); // iphone8 is on calling
// 繼承方式之一:
// 此方式優缺點:簡單易於實現, 但若爲子類新增屬性和方法,要在賦值了prototype以後執行, 沒法實現多繼承
Smartphone.prototype = new Phone('Xiaomi') // 繼承Phone對象實例的全部成員,靜態成員除外
let iphoneX = new Smartphone('iphoneX')
console.log(iphoneX.brand); // Xiaomi
console.log(iphoneX.model); // iphoneX
iphoneX.online(); // Xiaomi is going to online
iphoneX.onMsg(); // nokia message coming
iphoneX.oncalling(); // iphoneX is on calling
console.log(iphoneX instanceof Phone); // true
console.log(iphoneX instanceof Smartphone); // true
複製代碼
順帶提一下call方法也能夠實現繼承:ide
function Animal(name){
this.name = name;
this.showName = function(){
console.log(this.name);
}
}
function Cat(name){
Animal.call(this, name);
}
var cat = new Cat("Black Cat");
cat.showName(); // Black Cat
複製代碼
function Ball(name){
this.name = name;
this.showName = function () {
console.log('I am ' + this.name + ' from this');
}
}
Ball.prototype.showName = function () {
console.log('I am ' + this.name + ' from prototype');
}
let football = new Ball("football");
football.fly = function () {
console.log(this.name + ' is flying');
}
football.fly(); // football is flying
// 先從自身找,找不到在__proto__中去找,沒找到,去找上層__proto__,直到結果爲null爲止
football.showName(); // I am football from this
複製代碼