zoukankan      html  css  js  c++  java
  • JavaScript之面向对象学习三原型语法升级

    1、到目前为止,我们是时候分析下前面的使用原型语法来定义对象有哪些不足的地方,代码如下:

        function Person(){
        }
        Person.prototype.name="张三";
        Person.prototype.age=22;
        Person.prototype.job="coder";
        Person.prototype.sayName=function(){
            alert(this.name);
        }

    当我们为Person对象每添加一个属性和方法,就要敲一遍Person.prototype,而且Person.prototype没有体现出封装性;

    所以下面来改进原型语法,代码如下:

        function Person(){
        }
        Person.prototype={
            name:"张三",
            age:22,
            job:"coder",
            sayName:function(){
                alert(this.name);
            }
        }

    改进之后的原型语法将Person.prototype设置为等于一个以对象字面量形式创建的新对象。最终的结果相同,但有一个列外:constrcutor属性不再指向Person了。

    因为当我们每创建一个函数,同时就会创建一个prototype属性对象(原型属性对象),而这个对象会自动获得constructor属性。

    而我们在这里使用的语法,本质上完全重写了默认的prototype属性对象,因此constructor属性也就变成了新对象的constuctor属性(该属性指向Object构造函数),不在指向Person函数,所以尽管instanceof操作符还能返回正确的结果,但通过constructor属性来确定对象的类型已经不可能了,如下代码可以说明:

        function Person(){
        }
        Person.prototype={
            name:"张三",
            age:22,
            job:"coder",
            sayName:function(){
                alert(this.name);
            }
        }
        var person=new Person();
        alert(person instanceof Object); //输出:true  因为person是Object的实例(Object是所有类的基类)
        alert(person instanceof Person); //输出:true  因为person是Person的实例
        alert(person.constructor==Object);
        alert(person.constructor==Person); //输出false  说明Person构造函数的Person.prototype属性对象(原型对象)内的constructor属性已经不指向Person函数,而
    //是指向Object函数

    如果constructor属性真的很重要,我们可以向下面代码那样将它设回适当的值,代码如下:

        function Person(){
        }
        Person.prototype={
            constructor:Person, //自定义添加constructor属性,并让他指向Person函数
            name:"张三",
            age:22,
            job:"coder",
            sayName:function(){
                alert(this.name);
            }
        }
        var person=new Person();
        alert(person instanceof Object); //输出:true  因为person是Object的实例(Object是所有类的基类)
        alert(person instanceof Person); //输出:true  因为person是Person的实例
        alert(person.constructor==Object); //输出:false;  原因如下
        alert(person.constructor==Person); //输出:true  constructor:Person,=》在对象里面自定义了constructor属性,并让它指向了Person函数
        // 所以person.constructor重新指向了Person,而不是Object

    注意:以上这种方式添加constructor属性会导致它的[[Enumerable]]设为true,而原生的constructor属性是不可枚举的,所以我们需要用ECMAScript 5中定义的Object.definePropery()方法来重新定义constructor属性,使他变成不可枚举的属性,且值是指向对象构造函数的指针,代码如下:

       function Person(){
        }
        Person.prototype={
            name:"张三",
            age:22,
            job:"coder",
            sayName:function(){
                alert(this.name);
            }
        }
        Object.defineProperty(Person.prototype,"constructor",{
            enumerable:false,
            value:Person
        });
  • 相关阅读:
    PHP中单引号与双引号的区别分析
    utf8_unicode_ci与utf8_general_ci的区别
    [mysql-Ver5.6.23] windows版my.ini配置
    Gateway/Worker模型 数据库使用示例
    php 字符串 以 开头 以结尾 startWith endWith
    MySQL错误ERROR 2002 (HY000): Can't connect to local MySQL server
    vim变ide
    在Vue中使用样式
    Vue指令之`v-model`和`双向数据绑定
    Vue指令之事件修饰符
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/5846402.html
Copyright © 2011-2022 走看看