原型
- 原型是fucntion对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
// Person.prototype 原型
// Person.prototype = {} 是祖先
Person.prototype.name = "www"; // 属性
// 方法
Person.prototype.say = function () {
console.log("hhh");
}
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
- 利用原型的特点和概念,可以提取共有属性。
// Car.prototype.carName = "BMW";
// Car.prototype.height = 1400;
// Car.prototype.lang = 4900;
Car.prototype = {
carName : "BMW",
hieght : 1400,
lang : 4900
}
function Car(color, owner){
this.owner = owner;
this.color = color;
}
- 对象如何查看原型 ——> 隐式属性 __proto__
- 对象如何查看对象的构造函数 ——> constructor
function Person() {
}
Car.prototype = {
constructor : Person
}
function Car() {
}
var car = new Car();
此时car的构造器为Person
原型链
对象之间的多层继承可以构成一种原型链
对象的属性/方法从原型链中向上查找,当前对象没有该属性/方法,则查找其原型中是否存在该属性/方法。
// Grand.prototype.__proto__ 是 Object.prototype
// Object.prototype是最终原型
Grand.prototype.lastName = "Deng";
function Grand() {}
var grand = new Grand();
Father.prototype = grand;
function Father() {
this.name = "xuming";
}
var father = new Father();
Son.prototype = father;
function Son() {
this.hobbit = "smoking";
}
var son = new Son();
可以在原型中定义方法;
// a.sayName()
// sayName中的this指向:谁调用的方法,this指向谁
Person.prototype = {
name : 'a',
sayName : function(){
console.log(this.name);
}
}
function Person() {
this.name = 'b';
}
var person = new Person();
person.sayName(); // b
对象及其原型当中的操作要注意是引用还是赋值,下面的this.height ++ 即是this.height = this.height + 1因此,原型当中的height不会发生变化
Person.prototype = {
height : 100
}
function Person() {
this.eat = function(){
this.height ++;
}
}
var person = new Person();
person.eat(); // 执行完之后person的height为101, 但是原型中的不会发生变化
原型的create方法
可以通过的create方法创建对象,参数为对象原型:
// var obj = Object.create(原型);
var obj = {name : "sunny", age : 123};
var obj1 = Object.create(obj);
此时,obj为obj1的原型。
注意:并非所有的对象的最终原型都是Object.prototype
// obj无原型
var obj = Object.create(null);
原型中的方法可以被重写,重写后当前对象调用该方法时,即可覆盖原型中的方法。
Person.prototype = {
toString : function(){
return 'hehe';
}
}
function Person() {
}
var person = new Person();
person.toString(); // 'hehe'
// 示例2
var obj = Object.create(null);
obj.toString = function () {
return "aaa";
}
document.write(obj); // 输出aaa
call/apply 方法:改变this指向
call 方法可以利用别人的方法实现自己的功能
call 第一个参数会改变指向,让 Person 中的 this 全部指向 obj,其他参数正常传参
function Person(name, age){
//call之后导致obj代替了this
this.name = name;
this.age = age;
}
var person = new Person("amanda", 25);
var obj = {} // 对于obj利用别人的方法实现自己的功能
Person.call(obj, "cheng", 30);
示例2:
function Wheel(wheelSize, style) {
this.wheelSize = wheelSize;
this.style = style;
}
function Sit(c, sitColor) {
this.c = c;
this.sitColor = sitColor;
}
function Model(height, width, len){
this.height = height;
this.len = len;
this.width = width;
}
function Car(wheelSize, style, c, sitColor, height, width, len) {
Wheel.call(this, wheelSize, style);
Sit.call(this, c, sitColor);
Model.call(this, height, width, len);
}
var car = new Car(100, '花', '真皮', 'white', 1200, 1400, 4800);
区别:call 需要把实参按照形参的个数传进去;apply 需要传一个 arguments
function Person(name, age){
//call之后导致obj代替了this
this.name = name;
this.age = age;
}
var person = new Person("amanda", 25);
var obj = {} // 对于obj利用别人的方法实现自己的功能
Person.apply(obj, ["cheng", 30] );
知识和示例来源:渡一