• JavaScript对象 -构建


    首先,在js里,对象是由函数构建而成的。

    创建对象的几种模式

    1.工厂模式

    function person(name,age,job) {
        var o=new Object();
        o.age=age;
        o.name=name;
        o.job=job;
        o.sayname=function () {
            console.log(this.name);
        }
        return o;
    }
    
    var person1=person("1",1,"1");
    person1.sayname();
    //检测对象什么类型
    console.log(person1 instanceof Object);//true
    console.log(person1 instanceof person);//FALSE

    工厂模式解决了创建多个相似对象的问题,但是不知道如何知道一个对象的类型。

    2.构造函数模式

    function person(name,age,job) {
        this.name=name;
        this.age=age;
        this.job=job;
        this.sayname=function () {
            console.log(this.name);
        }
    }
    var person1=new person("1",1,"1");
    person1.sayname();

    console.log(person1 instanceof Object);//检测对象什么类型
    console.log(person1 instanceof person);//都是true

      与工厂模式不同点:

    1.没有显式创建对象

    2.属性方法赋予给this对象

    3.没有return语句

    创建对象使用new时,调用构造函数会有一下几步

    1.创建一个新对象

    2.构造函数的作用域给新对象

    3.执行构造函数的代码

    3.返回新对象

    任何函数,只要通过new来调用,那么他就可以作为构造函数,他的问题就是每个方法要在每个实例上重新构造一遍

    上述sayname方法等同于下

    this.sayname=new function("console.log(this.name)")

    如果再新建对象person2

    console.log(person1.sayname==person2.sayname) ;结果是FALSE

    当然我们可以把这些函数放在外面,在构造函数内调用,但是这样就毫无封装性。3.

    3.原型模式
    每个函数都有一个prototype属性
    function person() {
    }
    person.prototype.name="1";
    person.prototype.age=12;
    person.prototype.sayname=function () {
        console.log(this.name);
    }
    
    var person1=new person();
    person1.sayname();       //1
    var person2=new person();
    person2.sayname();       //1
    
    
    

    好处:让所有实例共享他的属性和方法

    如果实例添加一个新属性且新属性与原型中的属性重名,那么就在实例中创建该属性,该属性会屏蔽掉原型中的该属性。

    function person() {
    }
    person.prototype.name="1";
    person.prototype.age=12;
    person.prototype.sayname=function () {
        console.log(this.name);
    }
    
    var person1=new person();
    person1.name="2";
    person1.sayname();
    delete person1.name;//删除新添加的属性
    person1.sayname();  //会显示原型里的属性
    

    接下来是重点:

    function person() {
    }
    person.prototype={
        name:"1",
        age:12,
        sayname:function () {
            console.log(this.name);
        }
    }
    var friend=new person();
    console.log(friend instanceof Object);  //true
    console.log(friend instanceof person);   //true
    console.log(friend.constructor == person);  //false
    console.log(friend.constructor == Object);//true
    
    person.prototype.sayhi=function () {
        console.log("hi");
    }
    friend.sayhi(); //hi
    

    instanceof  判断一个变量是不是属于一个变量的实例。

    constructor 属性返回对创建此对象的数组函数的引用。

    friend是person的一个实例

    所以向person中添加 Protype时friend也可以引用。

    原型的动态性:

    function person() {
    }
    var friend=new person();
    console.log(friend instanceof Object);  //true
    console.log(friend instanceof person);   //true
    console.log(friend.constructor == person);  //true
    console.log(friend.constructor == Object);  //true
    console.log(friend.constructor);  //【Function:person】
    person.prototype={
        constructor:person,
        name:"1",
        age:12,
        sayname:function () {
            console.log(this.name);
        }
    }
    friend.sayname();//报错
    

    当执行到最后一句时会报错,原因是我们重写了整个原型对象。

    大致就是这个样子,person原本指向person Protype,在重写原型对象后指向了new person Protype,但是friend仍然指向原来的person Protype,所以出现错误。

    原型模式的问题:

    function person() {
    }
    person.prototype={
        constructor:person,
        friends:["a","b","c"]
    }
    var person1=new person();
    var person2=new person();
    person1.friends.push("d");
    console.log(person1.friends);//【a,b,c,d】
    console.log(person2.friends);//[a,b,c,d]
    

    会发现person2的friends也会有d

    针对包含引用类型值的属性:

    原因就是这个样子,person1引用Protype,所以修改person1就修改了person2。

    最常用的创建对象对象

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

    因为构造函数模式new时会创建一个新对象,而原型模式就是用于定义方法和共享属性。

    function person(name) {
        this.name=name;
        this.friends=['a']
    }
    person.prototype={
        constructor:person,
        sayname:function () {
            console.log(this.name);
        }
    }
    var person1=new person("1") ;
    var person2=new person("2") ;
    person1.friends.push("b");
    console.log(person1.friends);
    console.log(person2.friends);
    console.log(person1.friends==person2.friends);
    console.log(person1.sayname==person2.sayname);
    

      结果:

    [ 'a', 'b' ]
    [ 'a' ]
    false
    true

    到这相信大家对JS构建对象有了一定的了解了!

     
  • 相关阅读:
    常用软件整理列表
    红黑树的旋转(C语言)
    Linux 内核编译
    2017年9月11日
    2017年 9月10日
    2017年9月8号 开学第一天
    开始学习.net的第二天
    前端工作需要什么
    Kubernetes容器编排技术---Kubernetes基本概念和术语(一)
    监控工具之---Prometheus探索PromQL(二)
  • 原文地址:https://www.cnblogs.com/lilight/p/7520255.html
Copyright © 2020-2023  润新知