javascript--prototype

每个javascript函数自动prototype属性,使用prototype可以为类声明通用的属性,当一个对象被创建时,构造函数将会把它的属性的prototype赋给对象的内部属性__proto__

另外,javascript使用prototype实现继承机制

创建通用属性


不采用原型时:

function Fish(name, color){
    this.name = name;
    this.color = color;
    this.livePlace = "water";
    this.canSwim = function(){ console.log("I can swim");};
}

var cod = new Fish("cod","white");
var salmon = new Fish("salmon","black");

console.log(cod.livePlace);   //water
console.log(salmon.livePlace); //water
console.log(salmon.canSwim == cod.canSwim); //false

此时每申明一个实例Fish,都会有相同的属性值livePlace,有些重复,无法共享方法和属性

使用prototype,实例可以共享属性

function Fish(name, color){
    this.name = name;
    this.color = color;
}
 Fish.prototype.livePlace = "water";
 Fish.prototype.canSwim = function(){ console.log("I can swim");};

var cod = new Fish("cod","white");
var salmon = new Fish("salmon","black");

console.log(cod.livePlace);
console.log(salmon.livePlace);
console.log(salmon.canSwim == cod.canSwim); //true

例子中 实例共享属性livePlace和canSwim属性

 prototype 与 __proto__


1.所有函数的__proto__都指向Function.prototype

2. 对象的__proto__指向 其构造器的prototype

eg:

function Fish(name, color){
    this.name = name;
    this.color = color;
}
 Fish.prototype.livePlace = "water";
 Fish.prototype.canSwim = function(){ console.log("I can swim");};

var cod = new Fish("cod","white");
var salmon = new Fish("salmon","black");
var object = {};

console.log(Fish.__proto__ === Function.prototype); //true
console.log(cod.__proto__ === Fish.prototype);      //true
console.log(object.__proto__ === Object.prototype); //true
console.log(Object.getPrototypeOf(Fish) === Fish.__proto__); //true



注意: 浏览器不支持getPrototypeOf时可以使用Object.getPrototypeOf 替代

属性相关方法


hasOwnProperty() :是否含有某属性

isPrototypeOf() : 是否是..的原型

in 

 eg:

function Fish(name, color){
    this.name = name;
    this.color = color;
}
 Fish.prototype.livePlace = "water";
 Fish.prototype.canSwim = function(){ console.log("I can swim");};

var cod = new Fish("cod","white");
var salmon = new Fish("salmon","black");


console.log(Fish.prototype.isPrototypeOf(salmon));  //true
console.log(cod.hasOwnProperty("name")); //true
console.log("livePlace" in cod);  //true

 使用prototype实现继承


 方式一:

//父类

function People(name,age){
    this.name = name;
    this.age = age;
    this.species = "human";
    this.getName = function(){
        return this.name;
    }
    this.getAge = function(){
        return this.age;
    }
    this.sayHello = function(){
        console.log("hi,I am the father class");
    }
}

//子类
function Children(name, age){
    this.name = name;
    this.age = age;
}

Children.prototype = new People();
console.log(Children.prototype.constructor === People); //true
Children.prototype.constructor = Children;

var wish = new Children("wish");
console.log("the name of wish is:"+wish.getName());  //the name of wish is:wish 
console.log(wish.sayHello());  //hi,I am the father class 

注意:

1. prototype对象包含一个contructor属性,每一个实例也有一个constructor属性,默认调用prototype对象的constructor属性。Children.prototype = new People();给prototype赋了新的值, 此时Children.prototype.constructor值变为People,因而我们需要修改以保证原型链的正确性

2. 只要修改了prototype,一定要将新的prototype的constructor指向原来的构造函数

相关信息查看js类型判断及鸭式辨型

 方式二:

Children.prototype = People.prototype;

Children.prototype.constructor = Children;

注意:此种方式下如果 Children.prototype做了更改时,People.prototype也会相应更改

可以使用空函数作为中间介,以改善上面两种方式,如下:

Var F = function(){}
F.prototype = People.prototype;
Children.prototype = new F();
Children.prototype.constructor = Children;
原文地址:https://www.cnblogs.com/wishyouhappy/p/3738946.html