JS原型

原型

一:原型链(What?)

每个对象都会有一个构造器,每个构造器又会有一个原型。而原型本身也是一个对象,这意味这它必然有一个构造器,每个构造器又会有一个原型…….,这种结构会一直持续下去,最终取决于原型链(prototype chain)的长度,但其最后一环肯定是Object的内建对象,Because Object is the highest 父级对象

function foo(a,b){   this.a=a; this.b=b;  }
                foo.prototype={
                        add: function() {}
                        sub: function() {}
                }

上面这个函数以及原型中没有toString()方法,所以我们调toString()方法会调到Object的toString()

>var a=new foo(1,2); a.toString();
“[object Object]”
Q :若自身属性与原型属性同名怎么办?
A:对象自身属性的优先级高于原型属性

二:hasOwnProperty()属性:

        该属性可判断一个属性是自身属性还是原型属性。
>  function Toy(name) { this.name=name; }
>Toy.prototype.name='mirror';
>ar toy=new Toy('transform')
>toy.name    //调自身属性
"transform"
>toy.hasOwnProperty()
false
>toy.hasOwnProperty('name')    //判断该属性(‘name’)是否是调用者(toy)自身的
true
>toy.prototype.hasOwnProperty('name')    //语法错误
VM340:1 Uncaught TypeError: Cannot read property 'hasOwnProperty' of undefined(…)(anonymous function) @ VM340:1
>toy.constructor.prototype.hasOwnProperty('name')
true
>delete toy.name
true
>toy.hasOwnProperty('name')    //自身属性已被删除
false
>toy.name        //由于自身属性已被删除,所以此时调用的是原型中的
 "mirror" 

三:propertyIsEnumerable()属性

      该属性可以判段哪些属性是可以枚举的,一般内建函数都不可以枚举

————**一次测试**—————-

//Gadget小玩意
 function Gadget(name,color){
        this.name=name;
        this.color=color;
        this.getName=function() {
            return this.name;
        };
    }   
//以对象的形式添加属性
    Gadget.prototype={
        price: 100,
        //对....的评价
        rating: 3
 }
//webcam网络摄像头
var  toy=new Gadget('webcam','black');
//循环遍历toy构造方法与原型中的属性
for(var prop in toy){
    console.log(prop+'='+toy[prop]);
}
//VM:Virtual Memory虚拟存储器(忽略不看,已删)
 name=webcam
 color=black
 getName=function () {
        return this.name;
    }
price=100
 rating=3

//循环遍历toy构造方法中的属性
 for(var prop in toy){
    if(toy.hasOwnProperty(prop)){
        console.log(prop+'='+toy[prop]);
    }
}
 name=webcam
 color=black
 getName=function () {
        return this.name;
    }
//判断属性是否可以枚举
toy.propertyIsEnumerable('name')
true
toy.propertyIsEnumerable('constructor')
false
toy.constructor.prototype.propertyIsEnumerable('price')
false
toy.constructor.prototype.propertyIsEnumerable('rating')
false
//遍历对象中属性
for(var prop in toy){
    if(toy.constructor.prototype.hasOwnProperty(prop)){
        console.log(prop+'='+toy[prop]);
    }
}
//无任何输出 
 -------------------------------------------------***********************----------------------------------------------------
//与上面对比
function Gadget(name,color){
        this.name=name;
        this.color=color;
        this.getName=function() {
            return this.name;
        };
    }   
//直接加属性
    Gadget.prototype.price=100;
    Gadget.prototype.rating=3;
//遍历对象中属性
for(var prop in toy){
    if(toy.constructor.prototype.hasOwnProperty(prop)){
        console.log(prop+'='+toy[prop]);
    }
}
//输出结果
 price=100
 rating=3
g.propertyIsEnumerable('price');
false
g.constructor.prototype.propertyIsEnumerable('price')
true

----------***********二次测试************--------------
觉醒:记得加  constructor: Gadget,
  function Gadget(name,color){
        this.name=name;
        this.color=color;
        this.getName=function() {
            return this.name;
        };
    }   
    Gadget.prototype={
        constructor: Gadget,
        price: 100,
        rating: 3
 }
Object {price: 100, rating: 3}constructor: Gadget(name,color)price: 100rating: 3__proto__: Object
var a=new Gadget('webcam','black')
undefined
a.constructor.prototype.hasOwnProperty('price')
true
a.constructor.prototype.propertyIsEnumerable('price')
true
for(var prop in toy){
    if(a.constructor.prototype.hasOwnProperty(prop)){
        console.log(prop+'='+a[prop]);
    }
}
 price=100
 rating=3

四:isPrototypeOf()方法

         此方法可以告诉我们当前对象是否是另一个对象的原型,当我们不知道当前对象的原型是什么的情况下,可以通过Object.getPrototypeOf()方法来获取
var monkey={
    hair: true,
    feeds: 'bananas',
    breathes: 'air'
};
var fish={
    hair: false,
    feeds: 'smallFish',
    breathes: 'water'
}
function Human(name){
    this.name=name;
}
Human.prototype=monkey;
Human.prototype=fish;
Object {hair: false, feeds: "smallFish", breathes: "water"}
var george =new Human('George');
monkey.isPrototypeOf(george)
false
fish.isPrototypeOf(george)
true   
Object.getPrototypeOf(george)    //获取当前对象的原型
Objectbreathes: "water"feeds: "smallFish"hair: false__proto__: Object
Object.getPrototypeOf(george).feeds   
"smallFish"
 结论:一个对象只能有一个原型,后定义的原型会覆盖前面的
george.__proto__
Object {hair: false, feeds: "smallFish", breathes: "water"}
george.__proto__===fish
true

五:__proto__

var monkey={
    hair: true,
    feeds: 'bananas',
    breathes: 'air'
};

function Human(name){
    this.name=name;
}
Human.prototype=monkey;

var george =new Human('George');
george.spouse='heiha';
george.hacks='JavaScript';

george.spouse
"heiha"
george.hacks
"JavaScript"
george.feeds        //对象本身不存在feeds属性,是通过__proto__链接到原型中
"bananas"
//注意:__proto__与prototype并不是等价的,前者是某个实例对象的属性,后者则是属于构造器的属性
typeof george.__proto__
"object"
typeof george.prototype
"undefined"
typeof george.constructor.prototype
"object" 

六:扩展内建对象

Array.prototype.inArray=function(needle){
    for (var i = 0; i < this.length; i++) {
        if(needle===this[i]){
            return true;
        }
    };
    return false;
}
 //测试
var colors=['red','green','blue'];
colors.inArray('red');
true
//注意:在为内建对象扩展方法之前,先要判断内建对象中是否有该方法
 例:我们为String对象扩展trim()方法,该方法是ES5标准的一部分,老式浏览器不支持,所以为String扩展trim前先判断该浏览器是否有trim()方法(即该浏览器是否支持ES5)
if(typeof String.prototype.trim!=='function'){
    String.prototype.trim=function(){
        return this.replace(/^\s+|\s+&/g,'');
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值