• 创建对象的6种方式详解


    总结一下创建对象的几种方案:

    1.字面量创建

    1. let Person={};
    2. let Person={
    3. name:"Jason",
    4. age:21
    5. }

    开发的过程中最常见的方式,简单方便,内聚性强。

    2.new Object()

    1. var Person =new Object();
    2. Person.name = 'Jason'
    3. Person.age = 21
    上面这两种方式,创建同样的对象时,需要编写重复的代码。

    3.使用工厂模式创建对象

    1. function createPerson(name, age, height, address) {
    2. var p = {}
    3. p.name = name
    4. p.age = age
    5. p.height = height;
    6. p.address = address
    7. p.eating = function() {
    8. console.log(this.name + "在吃东西~")
    9. }
    10. p.running = function() {
    11. console.log(this.name + "在跑步~")
    12. }
    13. return p
    14. }
    15. var p1 = createPerson("张三", 18, 1.88, "广州市")
    16. var p2 = createPerson("李四", 20, 1.98, "上海市")
    17. var p3 = createPerson("王五", 30, 1.78, "北京市")
    18. // 工厂模式的缺点(获取不到对象最真实的类型)
    19. console.log(typeof p1) //object

           在使用工厂模式创建对象的时候,可以将创建对象的逻辑封装在一个函数里面,避免了重复代码,但是通过工厂函数创建的对象都是object类型,如果希望创建出来的对象有一个共同的类型,于是就出现了第四种创建对象的模式

    4.使用构造函数创建对象

    1. // 规范: 构造函数的首字母一般是大写
    2. function Person(name, age, height, address) {
    3. this.name = name
    4. this.age = age
    5. this.height = height
    6. this.address = address
    7. this.eating = function() {
    8. console.log(this.name + "在吃东西~")
    9. }
    10. this.running = function() {
    11. console.log(this.name + "在跑步")
    12. }
    13. }
    14. var p1 = new Person("张三", 18, 1.88, "广州市")
    15. var p2 = new Person("李四", 20, 1.98, "北京市")
    16. console.log(p1 instanceof Person) //true
    17. console.log(p2 instanceof Person) //true
    18. console.log(p1 instanceof Object) //true
    19. console.log(p2 instanceof Object) //true

    通过构造函数可以确保创建出来的对象都具有相同的类型

    但是这种方式也存在缺陷:

    每个对象里面都有公用的函数,意味着每次创建一个对象都会创建一个函数实例,因此可以这个函数放到外面,但是会污染全局作用域。

    就是每个方法都要在每个实例上重新创建一遍,方法指的就是我们在对象里面定义的函数。如果方法的数量很多,就会占用很多不必要的内存。于是出现了第五种创建对象的方法

    5.原型创建对象模式

    1. function Person(){}
    2. Person.prototype.name = 'Nike';
    3. Person.prototype.age = 20;
    4. Person.prototype.firends= [];
    5. Person.prototype.sayName = function(){ alert(this.name);};
    6. let person1 = new Person()
    7. person1.name = '哈哈' //往person1上面新增了name属性
    8. person1.friends.push('kobe') //会修改原型上的值,所有的实例都会受到影响
    9. let person2 = new Person()
    10. console.log(person2.friends) // ['kobe']

    这种方式将对象的属性和方法都保存到函数的原型上,创建出来的所有实例都可以访问到原型上的属性和方法,而不用在每个对象上都保存一份函数实例。

    缺点:

    1.这些属性并没有保存到对象自身上,而是通过原型链去访问

    2.如果修改了name属性,相当于在person1上面新增了属性name

    3.如果修改了一个引用数据类型,则会修改原型上面的值,所有的实例都会收到影响

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

    1. function Person(name, age, height, address) {
    2. this.name = name
    3. this.age = age
    4. this.height = height
    5. this.address = address
    6. }
    7. Person.prototype.eating = function() {
    8. console.log(this.name + "在吃东西~")
    9. }
    10. Person.prototype.running = function() {
    11. console.log(this.name + "在跑步~")
    12. }
    13. var p1 = new Person("why", 18, 1.88, "北京市")
    14. var p2 = new Person("kobe", 20, 1.98, "洛杉矶市")
    15. p1.eating()
    16. p2.eating()

    实例属性都是在构造函数中定义的,而所有实例方法则是在原型中定义。

            这种模式是ECMAScript中使用最广泛,认可度最高的一种创建自定义类型的方法,可以说这是用来定义引用类型的一种默认模式。

  • 相关阅读:
    Linux使用操作(一)
    设计模式浅析(五) ·单例模式
    LeetCode|动态规划|392. 判断子序列、115. 不同的子序列、 583. 两个字符串的删除操作
    【Android Framework系列】第15章 Fragment+ViewPager与Viewpager2相关原理
    高等数学(第七版)同济大学 习题7-1 个人解答
    最少失约 分数 10
    C++中的语法知识虚继承和虚基类
    Xubuntu16.04系统中安装create_ap创建无线AP
    一个简单的go使用grpc的案例
    设计模式——2. 工厂模式
  • 原文地址:https://blog.csdn.net/ICanWin_lll/article/details/133931129