最近感受,不知道該學點什麼,總是覺的本身什麼都不會,又感受是會點什麼,說是也知道面向對象,可是讓系統的說一下這裏面的東西,感受連不上線,成不了太系統的瞭解,因此就看了一下這的知識點,當本身的搬運工,僞裝是發了一篇文章,等本身查看方便;bash
function creatPerson(name,age,job) {
var o = new Object();
o.name= name;
o.age= age;
o.job= job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var p1 = creatPerson("hh",23,"worker");
var p2 = creatPerson("xx",26,"worker1");
p1.__proto__===p2.__proto__===Object.prototype;
對象的constructor 屬性最先是用來描述隊形類型的,檢測對象類型仍是 instanceof 更可靠
工廠模式建立的對象,constructor只有Object,這樣的實例沒有特定的類型;
複製代碼
function Person(name,age,job){
this.age = age;
this.name = name;
this.job = job;
this.sayName = function(){
alert(this.name)
}
//this.sayName = sayName; //解決方式
}
var p1 = new Person("hh",23,"worker");
var p2 = new Person("xx",26,"worker1");
//function sayName(){alert(this.name)} //解決方式
new的執行:
{
var obj ={};
obj.__proto__ = Person.prototype;
Person.call(obj);
return obj
}
p1 instanceof Person //true;
p2 instanceof Person //true;
p1 instanceof Object //true;
p2 instanceof Object //true;
這樣是得p1和p2實例有了特定的類型, Person;
複製代碼
優勢:他省略了構造函數初始化參數這個環節,原型中全部屬性都被不少實例共享,共享對函數很是合適,基本屬性也還行 經過在實例上添加同名屬性,可隱藏原型中的對應屬性值;app
缺點: 他的共享屬性,對於包含引用類型值的屬性 若是實例從新賦值沒什麼影響,和基本類型同樣,若是是操做修改 就有些問題了,會使得全部實例獲取到的該屬性都被修改, 因此也不單獨使用函數
function Person(){}
Person.prototype={
constructor:Person,
name:"ss",
friends:["s1","s2"],
sayName:function(){alert(this.name)}
}
var p1= new Person();
var p2= new Person();
p1.name = "p1"
console.log(p1.name) //p1
console.log(p2.name) //ss
p1.friends.push("s3");
console.log(p1.friends) //["s1","s2","s3"]
console.log(p2.friends) //["s1","s2","s3"]
複製代碼
用法:ui
function Person(){}
Person.prototype.name="ceshi"
Person.prototype.age =12;
Person.prototype.sayName = function(){
alert(this.name)
}
//這樣就是實現了代碼的共享
複製代碼
更簡單的寫法:
Person.prototype={
//constructor:Person,
name:"test",
age:12,
sayName:function(){alert(this.name)}
}
var friend = new Person();
friend instanceof Object //true
friend instanceof Person //true
friend.constructor==Person //false
friend.constructor==Object //true
這種簡單的寫法constructor 屬性就不在指向Person,而是指向Object構造函數;
此時能夠添加一個屬性constructor( 如上面註釋):可是此時的constructor 變成了可枚舉的屬性,原生是不可枚舉的,能夠考慮用Object.defineProperty()
複製代碼
var p1 = new Person();
<!-- 1 -->
Person.prototype.hh="ss";
p1.hh//ss 是能夠先建立實例在改邊原型在訪問的;
<!-- 2 -->
Person.prototype={
name:"ss"
}
p1.__proto__!=Person.prototype;
p1.name // undefined
複製代碼
function Person(age,name){
this.name = name;
this.age = age;
this.friends=[1,2,3]
}
Person.prototype={
constructor:Person,
sayName:function(){
alert(this.name)
}
}
var p1 = new Person("ss",12);
var p2 = new Person("ss3",123);
p1.friends.push(2);
console.log(p1.friends) // [1,2,3,2]
console.log(p2.friends)// [1,2,3]
複製代碼
function Person(name,age){
this.name = name;
this.age = age;
if(typeof this.sayName !="function"){//sayName沒初始化 這裏對一個方法判斷就能夠,而後初始化全部的,不必都每一個方法都判斷
Person.prototype.sayName=function(){alert(this.name)}
Person.prototype.sayAge=function(){alert(this.age)};
.....
}
****注意****:此處不能使用對象字面量形式重寫原型, 由於這中寫法是先建立的實例,而後在修改的原型,要是用對象字面量重寫原型,會切斷現有實例和新原型之間的聯繫, 致使方法實例上無此方法;
}
複製代碼
function Person(name,age){
var o = new Object();
o.name=name;
o.age=age;
o.sayName=function(){
alert(this.name)
};
return o;
}
var friends = new Person("xiaoming",12)
friends.asyName() // xiaoming
複製代碼
穩妥對象: 沒有公共屬性,而且其方法中不引用this的對象;this
function Person(name,age){
var o = new Object();
o.sayName=function(){
alert(name)
};
return o;
}
var friends = new Person("xiaoming",12)
friends.asyName() // xiaoming
複製代碼
繼承通常包括: 接口繼承:繼承方法和簽名; 實現繼承:繼承實際的方法;ECMAScript 只支持實現繼承spa
js主要經過原型鏈實現繼承,原型鏈的構建是經過將一個類型的實例賦值給另外一個構造函數的原型實現的prototype
Son.prototype = new Father();
//此時Son.constructor 被改寫爲了 Father;
Son.prototype.constructor = Son;
//給子類修改或者是添加方法的時候,要放在替換語句,改版子類原型語句以後,
//原型繼承時,不能使用字面量方式建立原型方法,這樣就從新寫了原型鏈了
Son.prototype.getName=function(){alert(this.name)};
複製代碼
function Son(){
Father.call(this,arguments)
}
複製代碼
function Father(){
this.name ="ss";
this.friends=[1,2,3,4]
}
function Son(){
Father.call(this);
}
Son.prototype = new Father(); // Son 原型得到Father上的屬性,name和friends
var son1 = new Son(); // 此時調用Son構造函數爲son1 實例上添加了屬性(name和friends), 這些屬性就屏蔽了原型中的同名屬性;
// 調用兩次Father構造函數的結果就是有兩組屬性,一組在實例上,一組在原型上;
複製代碼
function object(o){
function F(){};
F.prototype = o;
return new F();
}
// 和 Object.creat() 傳遞一個參數時候相同
複製代碼
function creat(origin){
var clone = object(origin); // 能夠是任何返回新對象的函數
clone.sayName(){alert("name")}; //這裏的函數每次都建立,不存在複用一說,
return clone;
}
複製代碼
function inherit(son,father){
var prototype = object(father.prototype);
// 上句話,建立父類原型的副本,prototype.__proto__ = Father.prototype;
// prototype 繼承constructor prototype.constructor 取的是原型鏈上,原型的Father.prototype.constructor, 爲 Father();即:prototype.constructor == prototype.__proto__.constructor // true
// prototype.hasOwnPrototyoe("constructor") //false
prototype.constructor = son; // 彌補重寫原型形成的默認屬性的修改;
//此時是給prototype 添加了constructor 屬性,賦值爲son, 屏蔽了原型上的constructor屬性
// prototype.hasOwnPrototype("constructor") // true
// prototype.constructor = son;
// prototype.__proto__.constructor = father
son.prototype = prototype;
// 給子類原型賦值爲父類原型的副本;
}
//使用:
function Father(){
this.name="11";
this.age=12;
}
Father.prototype.sayName=function(){
alert(this.name);
}
function Son(){
Father.call(this);
this.age=23;
}
inherit(Son,Father);
Son.prototype.sayAge=function(){
alert(this.age)
}
複製代碼