Javascript创建对象几种方法解析

Javascript面向对象编程一直是面试中的重点,将自己的理解整理如下,主要参考《Javascript高级程序设计 第三版》,欢迎批评指正。

通过字面量形式,创建对象:

        var person_1 = {name: "userName",age: 20}

工厂模式创建对象

    通过一个构造函数接收参数的方式构造对象,可无数次调用这个函数,通过改变参数构造不同的对象
         function createPerson(name,age){var o = new Object();//创建一个空的对象 -- 原料o.name = name;o.age = age;o.sayName = function(){       //给对象属性赋值 -- 加工过程alert(this.name)}return o; //返回加工后的对象 -- 出厂}var leo = createPerson('Leo',30);leo.sayName(); //"Leo"var cherry = createPerson('Cherry',20);cherry.sayName(); //"Cherry"
    缺点:工厂模式创建的对象,无法判断其类型

构造函数模式:

    类似Array,Object这种原生的构造函数,我们可以通过创建自定义的构造函数,从而定义自定义对象的类型和方法
        function Person(name,age){this.name = name;this.age = age;this.sayName = function(){alert(this.name);}}var leo = new Person('Leo',18);var cherry = new Person('Cherry',25);leo.sayName();cherry.sayName();
  1. 与工厂模式对比,几点不同:没有现实的创建空对象;直接将属性和方法赋值给this;不需要return
  2. 通过New操作符创建Person对象的新实例:①创建一个新的对象 ②this指向这个新对象(作用域)③执行构造函数中的代码,对新对象添加属性和方法④返回新对象
  3. 通过instanceof检测对象类型,发现通过Person构造函数创建的对象,即使Person类的实例,又是Object对象的实例 - 创建自定义的构造函数表明可以将它的实例标识为一种特定的类型
        alert(leo instanceof Person); //true alert(leo instanceof Object); //true 所有对象都继承自Object
  1. 区分构造函数和普通函数
    ①. 任何函数通过new操作符调用,就可做为构造函数
    ②. 自定义的构造函数,不通过new调用,与普通函数没有区别
        Person('window',100);//直接调用,相当于将Person类的属性方法直接添加到了this上window.sayName(); //window
  1. 缺点:通过构造函数,每个方法都要在实例上重新创建一遍,每个实例的sayName方法,相当于执行this.sayName = new Function("alert(this.name)")单独创建出来的
        alert(leo.sayName==cherry.sayName);//false

原型模式:

  1. 创建的每个函数都有prototype属性,这个属性指向一个其属性和方法由某个特定类的所有实例共享的对象,利用prototype,我们就可将定义对象实例的信息放在原型对象中,不必在构造函数中定义。
        function Person(){} //构造函数变成空Person.prototype.name = 'Leo';Person.prototype.age =30;Person.prototype.sayName = function(){alert(this.name);}var person1 = new Person();var person2 = new Person();alert(person1.sayName==person2.sayName);//true 将sayName方法定义在Person的prototype属性中,可由多个不同的实例共享//简化写法:function Person() { } //构造函数变成空Person.prototype = {name: 'Leo',age: 30,sayName: function () {alert(this.name);}}    var person1 = new Person();var person2 = new Person();
  1. 只要创建一个新函数,就会为该函数创建一个prototype属性,这个属性指向原型对象。在我们创建的对象person1和person2中都包含一个内部属性,该属性指向Person.prototype,因此两个实例都可以调用原型中的sayName()方法。Object.getPrototypeOf()方法可以更方便的取得一个对象的原型.
      alert(Person.prototype.isPrototypeOf(person1));//truealert(Person.prototype.isPrototypeOf(person2));//truealert(Object.getPrototypeOf(person1)==Object.getPrototypeOf(person2));//true
  1. 给一个对象添加一个属性,这个属性会屏蔽原型对象中存储的同名属性,通过hasOwnProperty()方法可判断是实例对象中的属性,还是原型中的属性;通过in运算符,可以判断在对象上能否找到某属性,而不区分是实例属性还是原型属性,for in循环中只会遍历可访问、可枚举的属性。
        person1.name='Nancy';alert(person1.name);//Nancyalert(person1.hasOwnProperty("name"));//True 实例对象上的属性alert(person2.hasOwnProperty("name"));//false 原型中的属性alert("name" in person1);//truealert("name" in person2);//truefor(key in person1){alert(`${key}:${person1[key]}`)}
  1. 原型模式的缺点:①缺少向构造函数传递初始化参数这一环节,使得同一个对象的所有实例在默认情况下都会取得相同的属性值。②在实例中修改引用属性的值,会影响其他的实例。
        function Newperson(){}Newperson.prototype = {constructor : Newperson,name:"Tony",age:30,job:"Developer",friends:['Leo','Cherry'],sayName:function(){alert(this.name);}}let newPerson1 = new Newperson();let newPerson2 = new Newperson();alert(newPerson1.friends);//Leo, Cherryalert(newPerson2.friends);//Leo, CherrynewPerson1.friends.push('Mai');//friends属性引用数组在Newperson.prototype而非newPerson1中,newPerson1.friends和newPerson2.friends指向的是同一个引用alert(newPerson1.friends);//Leo, Cherry, Maialert(newPerson2.friends);//Leo, Cherry, Maialert(newPerson1.friends === newPerson2.friends);//true

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

  1. 组合使用构造函数模式和原型模式是创建自定义类型的常见方式,构造函数用于定义实例属性,原型模式用于定义方法和共享属性。
      function Person(name,age,job){this.name = name;this.age = age;this.job = job;this.friends = ["Leo","Cherry"];}Person.prototype = {constructor:Person,sayName:function(){alert(`${this.name} is a ${this.job}.`);//公共方法}}let person1 = new Person('Mai',18,'actor');let person2 = new Person('Bob',25,'developer');person1.sayName();person2.sayName();alert(person1.friends == person2.friends);//false friends属性在构造函数中定义,不在原型中,两个实例不会相互影响person1.friends.push('Tony');person2.friends.push('Melody');alert(person1.friends);//Leo, Cherry, Tonyalert(person2.friends);//Leo, Cherry, Melody

转载于:https://www.cnblogs.com/Nancy-wang/p/9022143.html

Javascript创建对象几种方法解析相关推荐

  1. 创建JAVASCRIPT对象3种方法

    创建JAVASCRIPT对象3种方法 方法一:直接定义并创建对象实例 var obj = new Object();    //创建对象实例 //添加属性obj.num = 5;   //添加属性 o ...

  2. 在js中加html_在HTML文档中嵌入JavaScript的四种方法

    在HTML里嵌入JavaScript 在HTML文档里嵌入客户端JavaScript代码有4中方法: 1.内嵌,放置在标签之间  (少): 2.放置在有 3.放置自HTML事件处理程序中,该事件处理程 ...

  3. java list 删除 遍历_Java list利用遍历进行删除操作3种方法解析

    Java list利用遍历进行删除操作3种方法解析 这篇文章主要介绍了Java list利用遍历进行删除操作3种方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需 ...

  4. swift:使用NSJSONSerialization和SwiftyJSON两种方法解析网络返回的json格式数据

    在我的博客(下面)两个实验的基础上,使用NSJSONSerialization和SwiftyJSON两种方法解析网络返回的json格式数据,参照视频实现的"天气信息"小实验 1 创 ...

  5. java 遍历删除list_Java list利用遍历进行删除操作3种方法解析

    这篇文章主要介绍了Java list利用遍历进行删除操作3种方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Java三种遍历如何进行list ...

  6. 10种方法解析LOGO设计中的中文字体设计

    10种方法解析LOGO设计中的中文字体设计 1. 连接法--结合字体特征将笔画相连接的形式 2. 简化法--根据字体特点,利用视觉错觉合理地简化字体部分笔画的形式 3. 附加法--在字体外添加配合表现 ...

  7. C#后台调用前台javascript的五种方法

    第一种,OnClientClick    (vs2003不支持这个方法) <asp:Button ID="Button1" runat="server" ...

  8. java 运行main_使用maven运行Java Main的三种方法解析

    maven使用exec插件运行java main方法,以下是3种不同的操作方式. 一.从命令行运行 1.运行前先编译代码,exec:java不会自动编译代码,你需要手动执行mvn compile来完成 ...

  9. java main 运行_使用maven运行Java Main的三种方法解析

    导读热词 maven使用exec插件运行java main方法,以下是3种不同的操作方式. 一.从命令行运行 1.运行前先编译代码,exec:java不会自动编译代码,你需要手动执行mvn compi ...

最新文章

  1. 有哪些可以免登录的视频会议软件/服务?
  2. cdh编译安装支持各种压缩格式
  3. syslog-ng 配置说明
  4. 如何在SAP S/4HANA Fiori UI上创建新的扩展字段
  5. SAP CRM Category创建场景
  6. 53pagecontext对象
  7. python pandas read_csv 迭代器使用方法_pandas.read_csv参数详解(小结)
  8. 五分钟读懂UML类图
  9. IOS开发之把 Array 和 Dictionaries 序列化成 JSON 对象
  10. 曼昆经济学原理_第五版[1].txt.doc
  11. requests+正则表达式爬取豆瓣读书top250
  12. 容联七陌×惠州燃气丨用服务之光,点燃美好生活
  13. es配置中文和拼音分词器
  14. 《东周列国志》第三十五回 晋重耳周游列国 秦怀嬴重婚公子
  15. Learned Image Compression with Discretized Gaussian Mixture Likelihoods and Attention Modules文献复现
  16. 集线器、交换机、路由器、中继器及网关、网桥之间的区别
  17. Qua Vadis Eclipse? 第二部分
  18. 安装windows和android双系统,真正的安卓Windows双系统,RemixOS Windows共存系统安装+附带ROOT+大分区...
  19. 机房温度过高应这样预防
  20. C语言坐标旋转,c语言矩阵的顺、逆时针旋转

热门文章

  1. 关于share prefrences功能的一些理解
  2. ORA-00845 方案解决
  3. mysql的未提示输入密码
  4. 问题 K: n个数的最大值和最小值
  5. python中yield的使用_python中yield的用法详解-转载
  6. 欧科云链OKLink:以太坊上借贷协议借款量突破百亿美元
  7. dYdX 2020年度回顾:累计交易量增长40倍
  8. SAP License:GB01中替代字段释放
  9. SAP License:SAP顾问你算哪根葱?
  10. SAP License:SAP Netweaver