一、原型:是function對象的一個屬性,是構造函數製造出對象的公共祖先。通過該構造函數產生的對象,可以繼承原型的屬性和方法。原型也是對象。
提取公有屬性:
//Person.prototype = {},生來就有,是person1,person2...的爹
Person.prototype = {
//constructor : Person,
lastName : 'James',
firstName : 'Lebron',
gender : 'male',
age : 36
}
function Person(club,score){
//var this = {
// __proto__ : Person.prototype(在person1訪問屬性時,如果自己身上沒有,就會沿着__proto__的指向去找)
//}
this.club = club;
this.score = score;
//return this;
}
var person1 = new Person('Laker', 10000);
var person2 = new Person('Heat', 8000);
增:Person.prototype.wife = 'Laurel';
刪:delete Person.prototype.lastName; 從person1下手是刪不掉
改:Person.prototype.lastName = 'King'; 在person1身上是改不掉的,除非是引用值的調用式修改,詳情看下文。
查:person1.lastName;
Person.prototype生來有constructor屬性,指向Person(),可以手動更改。
其中person1可以通過person1.constructor找到構造它的函數Person()。
二、原型鏈:
//Grand.prototype.__proto__ = Object.prototype
//Grand.prototype.lastName = 'James';
function Grand(){}
var grand = new Grand();
Father.prototype = grand;
function Father(){
this.fisrtName = 'Lebron';
this.club = {
no1 : 'Heat',
no2 : 'Laker'
}
}
var father = new Father();
Son.prototype = father;
function Son(){
this.hobbit = 'basketball';
}
var son= new Son();
增刪改查,類似原型增刪改查
說到其中的改:son.club.no3 = 'Rocket'; 可以實現引用值的調用式修改。
1、另一種構造對象的方式:
var obj = Object.create(原型)
絕大多數對象的最終都會繼承自Object.prototype(Object.create(null)是個例外)。
2、關於toString(),觀察下列代碼輸出。
Object.prototype上本身含有toString方法,但輸出形式是"[object Xxxxx]",爲何數字,字符串,數組,布爾會輸出不同形式?
123.toString();//會報錯,首先識別成浮點型
var num = 123;
num.toString(); //返回"123"
var str = 'abc';
str.toString(); //返回"abc"
var arr = [1,2];
arr.toString(); //返回"1,2"
var obj = {};
obj.toString(); //返回"[object Object]"
拿數字舉例,儘管Number.prototype.__proto__ = Object.prototype。但Number.prototype上有重寫的toString方法,並不會調用Object.prototype本身的方法。同樣:
String.prototype上有重寫的toString方法
Array.prototype上有重寫的toString方法
Boolean.prototype上有重寫的toString方法
如何來證明呢?還記得初學JavaScript使用過的document.write。我們來看一下它的底層原理。
var obj = Object.create(null);
document.write(obj);//會報錯
var obj = Object.create(null);
//因爲此時的obj對象沒有prototype,也不存在toString方法,我們爲其手動添加。
obj.toString = function(){
return '呵呵呵';
}
document.write(obj);//打印結果爲呵呵呵。證明調用的是toString
3、JavaScript小bug:0.14 * 100 = 14.000000000000002
是由於JavaScript精度不準造成的,正常計算的範圍是小數點前後各16位。我們應該儘量避免小數操作,如果不能避免,可以使用Math.floor/Math.ceil。
三、call和apply,改變this指向,傳參列表不同
function Person(name, age, gender){
//this == obj
this.name = name;
this.age = age;
this.gender = gender;
}
var person = new Person('James', 36, 'male');
var obj = {};
//Person(); === Person.call();
Person.call(obj, 'Lau', 128, 'male');
在開發過程中,想用別人的方法實現自己的功能怎麼辦,還用說,call它啊,參數第一位把填自己的對象。
如下列代碼,想要借用上圖Person的方法來實現自己的功能,可按照下列操作。
function Student(tel, grade){
//var this = {__proto__ : Student.prototype}
Person.call(this, name, age, gender);
this.tel = tel;
this.grade = grade;
}
var student = new Student('Jack', 128, 'male', 17600001234, 2019);
call和apply的唯一不同之處在於傳參列表,apply的傳參形式爲arguments。
以上內容屬二哥原創,整理自 "渡一教育Javascript課程" ,一個值得推薦的"渡一教育"。