设为首页 加入收藏

TOP

JavaScript | 创建对象的9种方法详解(二)
2017-10-10 12:59:35 】 浏览:10213
Tags:JavaScript 创建 对象 方法 详解
象添加其他的属性和方法

创建自定义构造函数后,原型对象默认只取得constructor属性,其他方法从Object继承而来,原型指针叫[[prototype]],但在脚本中没有提供访问方式,在其他实现中这个属性不可见,但浏览器为对象增加了一个_proto_属性。

原型指针的连接存在于实例与构造函数的原型对象之间,而不是存在于实例与构造函数之间。

图解:

  • 关于原型的属性:

    实例:person1,原型:Person

    查找属性时先查找person1中的属性有没有name,如果有则返回person1.name的值,如果没有则查找原型Person中有没有name,参照原型链与对象的结构

  • in 操作符和 hasOwnProperty() 区别:

    in操作符:无论属性是在实例还是原型中,都返回true,只有在不存在的情况下才会false

    hasOwnProperty(): 只有在调用的实例或原型中的属性才会返回true

  • 案例中整个重写原型的问题图解:

    <<script.js>>

  • "use strict";
    // *****************************************************************
    // 原型模式
    function Person() {};
    Person.prototype.id = 0;
    Person.prototype.name = "name0";
    Person.prototype.sayName = function() {
        console.log(this.name);
    };
    
    var person1 = new Person();
    person1.sayName();
    var person2 = new Person();
    person2.name = "name2";
    person2.sayName();
    console.log(person1.sayName == person2.sayName);
    Person.prototype.name = "111"; // 对原型中的初始值修改后,所有的子实例都会修改初始值
    person1.sayName();
    person2.name = "222";
    person2.sayName();
    delete person2.name; // 删除person2.name
    person2.sayName(); // 111,来自原型
    
    // *****************************************************************
    // isPrototypeOf():确定原型关系的方法
    console.log(Person.prototype.isPrototypeOf(person1)); // true
    var person3 = new Object();
    console.log(Person.prototype.isPrototypeOf(person3)); // false
    // getPrototypeOf():返回原型[[prototype]]属性的方法
    // in操作符
    console.log(Object.getPrototypeOf(person2)); // 包含Person.prototype的对象
    console.log(Object.getPrototypeOf(person2) == Person.prototype); // true
    console.log(Object.getPrototypeOf(person2).name); // 111,初始值
    
    // hasOwnProperty():检测一个属性是唉实例中还是在原型中
    console.log(Person.hasOwnProperty("name")); // true
    console.log(person1.hasOwnProperty("name")); // false 在上面的操作中没有为person1添加name
    console.log("name" in person1); // true
    person2.name = "333";
    console.log(person2.hasOwnProperty("name")); // true
    console.log("name" in person2); // true
    
    // p.s.Object.getOwnPropertyDescriptor()方法必须作用于原型对象上
    console.log(Object.getOwnPropertyDescriptor(person1, 'name')); // undefined
    console.log(Object.getOwnPropertyDescriptor(Person, 'name')); // Object{...}
    
    // *****************************************************************
    // 简单写法
    // 以对象字面量的形式来创建新的对象原型
    // p.s.此时constructor属性不再指向Person,而是指向Object,因为此处重写了整个对象原型
    function Per() {};
    Per.prototype = {
        id: 0,
        name: "Per_name",
        sayName: function() {
            console.log(this.name);
        }
    }
    // 在该写法中要重写constructor属性,如果直接重写constructor属性会导致[[Enumberable]]=true,可枚举,原生的constructor属性不可枚举
    // 正确的重写方法
    Object.defineProperty(Per.prototype, "constructor", { enumberable: false, value : Per });
    var per1 = new Per();
    console.log(person1.constructor); // Person()
    console.log(per1.constructor); // Per(),如果不加constructor:Per返回Obejct()
    
    // 图解见上部
    // 如果直接重写整个原型对象,然后在调用per1.sayName时候会发生错误,因为per1指向的原型中不包含以改名字明明的属性,而且整个重写的对象无法修改
    // function Per() {};
    // var per1 = new Per();
    // Per.prototype = {
    //     constructor:Per,
    //     id: 0,
    //     name: "Per_name",
    //     sayName: function() {
    //         console.log(this.name);
    //     }
    // }
    // var per2 = new Per();
    // per1.sayNam
    首页 上一页 1 2 3 4 下一页 尾页 2/4/4
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇JavaScript | 创建对象的9种方法.. 下一篇海量数据系统之道

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目