對象、原型
原型
原型是構造函數 Function的一個屬性,它定義了構造函數製造出的對象的公共祖先。通過該構造函數產生的對象,可以繼承該原型的屬性和方法。原型也是對象。利用原型的特點和概念,可以提取共有屬性。
對象的有個隱式的屬性:__proto__ ,指向構造函數的原型 Function.prototype
對象原型具有指向構造函數的屬性:constructor。
<script type = "text/javascript">
//函數的原型,相當於對象繼承至其它對象的屬性和方法
Car.prototype ={
carName : "BMW",
heitht : 1400,
lang : 4900,
run : function(){
console.log("Runing !!");
}
}
Car.prototype.width = 1600;
function Car(color,owner){
//new 對象時 創建 this 屬性
//this 屬性默認添加 __proto__ 屬性(這裏存對象的原型)
//this 屬性默認添加 constructor 屬性(這裏存對象的構造函數)
this.owner = owner;
this.color = color;
}
var car = new Car("red","sunny");
console.log("car.__proto__",car.__proto__);//獲取對象的原型
console.log("car.constructor",car.constructor);//獲取對象的構造函數
function Person(){}
var per = new Person();
console.log("per.__proto__",per.__proto__);//獲取對象的原型
console.log("per.constructor",per.constructor);//獲取對象的構造函數
</script>
原型鏈
對象的 prototype 的 prototype 的 prototype ……Object 的 prototype (等於null,null 無原型,最後一級)。這種關係就是原型鏈。
<script type = "text/javascript">
//原型鏈的演示,
//原型可以從最後一級訪問到頂級,訪問子對象的屬性時,如子對象沒有這個屬性,去查詢父對象,直到找到屬性並返回。
//原型鏈最頂級對象爲 Object
Grand.prototype.lastName = "Zhang"
function Grand(){this.another = "yeye";}
var grand = new Grand();
Father.prototype = grand;
function Father(){this.firstName = "jiayi";}
var father = new Father();
Son.prototype = father;
function Son(){this.like = "play game";}
var son = new Son();
console.log(son.like,son.firstName,son.another,son.lastName);//獲取屬性值,在原型鏈上各層級對象的屬性值。
console.log(son.toString());//會調用原型鏈上的Object對象的方法。
console.log(son);//可以在控制檯上查詢到原型鏈的結構。對象的__proto__屬性
</script>
通過原型創建對象
<script type = "text/javascript">
Father.prototype.lastName = "Zhang"
function Father(){this.another = "baba";}
var Father = new Father();
var son = Object.create(Father);//通過原型創建一個對象,創建的對象的原型就是傳入的參數
var son = Object.create(null)//創建一個無原型的對象。
//null undefined 無原型
//包裝類 Number String Boolean 等有原型
</script>
重寫原型的屬性和方法
<script type = "text/javascript">
Father.prototype={
toString:function(){//如果不寫這個方法,將訪問Object的toString方法。
return "返回新的信息";
}
}
function Father(){}
var father = new Father();
console.log(father.toString());
</script>
Call/apply
可修改this指向
通過call /apply可以給 obj 對象添加 Person 的屬性,差別在於傳參方式,call傳一個對象和多個參數,apply傳一個對象和一個參數數組。
<script type = "text/javascript">
function Person(name,age){
//call 調用後 this => obj
this.name = name;
this.age = age;
this.play = function(){
console.log(this.name + " play !")
}
}
var per = new Person('zhang',18);
var obj = {phone:133}
var obj1 = {phone:133}
console.log(obj);
Person.call(obj,'li',20);//通過call 可以給 obj 對象添加 Person 的屬性。
Person.apply(obj1,['li',20]);//通過apply 可以給 obj 對象添加 Person 的屬性。
console.log(obj);
console.log(obj1);
obj.play();
obj1.play();
//通過call 可以給 Student 添加 Person 的屬性。
function Student(name,age,techer){
Person.call(this,name,age);
this.techer = techer;
this.study = function(){
console.log(this.name + " study !")
}
}
//通過apply 可以給 Student 添加 Person 的屬性。
function Student1(name,age,techer){
Person.apply(this,[name,age]);
this.techer = techer;
this.study = function(){
console.log(this.name + " study !")
}
}
var stu = new Student("wang",12,"liu");
var stu1 = new Student1("wang",12,"liu");
console.log(stu);
console.log(stu1);
stu.play();
stu.study();
stu1.play();
stu1.study();
</script>
new Student1("wang",12,"liu");
console.log(stu);
console.log(stu1);
stu.play();
stu.study();
stu1.play();
stu1.study();
</script>