JS中的原型详解

每一个函数都有一个prototype属性,指向这个函数的原型对象,默认情况下,
原型对象都会有一个constructor(构造函数)属性指向这个函数。
如:
    function A(){
        //....
    }
    console.log(A.prototype.constructor == A);  // true

当函数作为构造函数创建一个对象时,该对象就会有一个隐式内部属性[[prototype]]指向该函数的原型对象。
    function A(){
        //....
    }
    var a = new A();   //  a.[[prototype]] = A.prototype 即a的原型是A.prototype
判断是否是其原型的方法: isPrototypeOf()
获取对象的原型的方法:Object.getPrototypeOf()

原型对象中定义的属性和方法是被所有的实例对象所共享的,
当读取某一个对象的属性时,首先在对象本身中查找,如果找到则返回属性值,
如果没有找到,则会沿着这个对象的原型链依次查找,直到找到或者是返回null。

虽然可以通过对象实例访问原型对象中的值,但是不可以通过对象实例修改原型对象中的值。
如果实例对象中新添加的属性与其原型对象中的属性同名,那么就会屏蔽原型对象中的属性。
判断对象是否有自身有某属性而不是在原型中的方法: hasOwnProperty()

    function Person(name,age){
        this.name = name;
        this.age = age;
    }
    Person.prototype = {
        constructor:Person,
        school: "淮海工学院",
        sayName:function(){
            console.log("Hi, i am " + this.name);
        }
    }
    var tom = new Person("TOM",23);
    console.log(tom.name);     // 在tom对象本身找到
    console.log(tom.school);   // 在原型对象中找到
    tom.sayName();             // 在原型对象中找到

使用in操作符,判断是否可以通过对象访问该属性,不管是自身的,还是原型中的,是的话返回true
    if("name" in tom){  // true
        //....
    }
for-in循环 返回的是所有可以通过对象访问的,可枚举的属性,
    for(prop in tom){
        console.log(prop);
    }

---------------------

    function Person(){
        //....
    }
    Person.prototype.city = "连云港";
    Person.prototype.school = "淮海工学院";
    Person.prototype.sayHi = function(){
        alert("hello");
    }
    Person.prototype.constructor == Person  // true
    每创建一个函数的同时会创建其prototype对象,
    这个对象会自动获得一个指向这个函数的constructor属性,
    所以每一个对象都有constructor属性(来自原型)

重写整个原型对象:
    Person.prototype = {
        city: "连云港",
        school: "淮海工学院",
        sayHi: function(){
            alert("hello");
        }
    }
    因此该原型对象的constructor不再指向Person,而是Object

重写原型对象带来的问题:

    function Student(){
        //.....
    }
    var jerry = new Student();
    Student.prototype ={
        constructor: Student,
        school: "MIT",
    }
    console.log(jerry.school);  // undefined

    jerry的原型对象是最初的原型对象,其constructor是Student
    而接下来把Student的原型修改为另一个对象,但是Jerry引用的仍然是最初的原型

    修改原型对象会切断现有原型与任何之前已经存在的对象实例之间的联系,
    他们(如jerry)引用的仍然是最初的原型

    解决办法就是:在修改原型之后再创建对象。

构造函数模式--原型模式 组合使用

    function Person(name,age){
        this.name = name;
        this.age = age;
    }
    Person.prototype = {
        constructor: Person,
        sayName: function(){
            alert(this.name);
        }
    }
在这种模式中,实例属性在构造函数中定义,而所有实例共享的属性(如constructor)和方法在原型中定义,这是使用最广泛,认同度最高的一种创建自定义类型的方法,可以说是创建引用类型的一种默认模式。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值