Javascript创建对象的几种方式?

javascript 中常见的创建对象的几种方式:

 1. 使用Object构造函数创建;

使用Object构造函数来创建一个对象,下面代码创建了一个person对象,并用两种方式打印出了Name的属性值。

var person = new Object();
person.name="kevin";
person.age=31;
alert(person.name);
alert(person["name"])

2. 使用对象字面量创建一个对象;

var person ={name:"Kevin",age:31,5:"Test"
};
alert(person.name);
alert(person["5"]);

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

返回带有属性和方法的person对象。

function createPerson(name, age,job){var o = new Object();o.name=name;o.age=31;o.sayName=function(){alert(this.name);};return o;
}
createPerson("kevin",31,"se").sayName();

用函数来封装以特定接口创建对象的细节,解决了创建多个相似对象的问题,但是没有解决对象识别的问题(怎么知道一个对象的类型)。

4. 使用自定义构造函数模式创建对象;

这里注意命名规范,作为构造函数的函数首字母要大写,以区别其它函数。这种方式有个缺陷是sayName这个方法,它的每个实例都是指向不同的函数实例,而不是同一个。构造函数模式,构造函数添加属性和方法,使用的时候new一个自定义的对象

function Person(name,age,job)
{this.name=name;this.age=age;this.job=job;this.sayName=function(){alert(this.name);};
}var person = new Person("kevin",31,"SE");
person.sayName();

new一个构造函数的内部操作步骤:

1)、创建一个新对象;

2)、将构造函数的作用域赋给新对象(因此this就指向了这个新对象);

3)、执行构造函数中的代码;

4)、返回新对象。

使用构造函数创建的实例,都会有一个constructor属性,指向构造函数。

创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型。这正是胜过工厂模式的地方。

与普通函数的区别在于new调用,不用new来调用,与普通函数无差。

不使用new调用的时候,就相当于window调用了构造函数,属性和方法都被添加到了window对象上去。

也可以这样使用:(call就是为了改变上下文环境而生)

var o = new Object();
Person.call(o,"Dadaoshenyi",25,"Enginner");
o.sayName();//"Dadaoshenyi"

构造函数创建对象的问题:每个方法都要在实例上重写一遍。由于函数也是对象,因此每次定义一个函数,也就实例化了一个对象。

5. 使用原型模式创建对象;

解决了方法4中提到的缺陷,使不同的对象的函数(如sayFriends)指向了同一个函数。

但它本身也有缺陷,就是实例共享了引用类型friends,从下面的代码执行结果可以看到,两个实例的friends的值是一样的,这可能不是我们所期望的。原型模式,定义构造函数,构造函数原型上添加属性和方法。 

function Person(){}Person.prototype = {constructor : Person,name:"kevin",age:31,job:"SE",friends:["Jams","Martin"],sayFriends:function(){alert(this.friends);}
};
var person1 = new Person();
person1.friends.push("Joe");
person1.sayFriends();//Jams,Martin,Joe
var person2 = new Person(); 
person2.sayFriends();//James,Martin,Joe

构造函数的原型||对象实例的内部指针([[Prototype(__proto__)]]指向Person.prototype)。

实例对象的内部指针指向构造函数的原型。

原型模式的优点:自定义的构造函数,可以让所有的对象实例共享原型对象所包含的属性和方法。原生的引用类型也是采用这种模式。

问题在于:1、省略了构造函数传递参数的步骤。2、所有实例共享方法和属性,这样,实例修改原来的属性或者方法,将会在所有的实例上表现出来。被捆绑到了一起。只是一个引用,不是一个副本。

6. 组合使用原型模式和构造函数创建对象;

解决了方法5中提到的缺陷,而且这也是使用最广泛、认同度最高的创建对象的方法。组合使用构造函数模式和原型模式,最常用的一种模式。 

function Person(name,age,job)
{this.name=name;this.age=age;this.job=job;
this.friends=["Jams","Martin"]; } Person.prototype.sayFriends=function() {alert(this.friends); };
// Person.prototype = {
// constructor: Person,
// sayFriends: function() {
// alert(this.friends);
// }
// };
var person1 = new Person("kevin",31,"SE");
var person2 = new Person("Tom",30,"SE");
person1.friends.push("Joe");
person1.sayFriends();//Jams,Martin,Joe
person2.sayFriends();//Jams,Martin

优点:使用构造函数来创建实例属性,且可以修改设定的值。使用原型创建共享方法和共享的属性。最大限度的节省了内存。

7. 动态原型模式;

这个模式的好处在于看起来更像传统的面向对象编程,具有更好的封装性,因为在构造函数里完成了对原型创建。这也是一个推荐的创建对象的方法。动态原型模式,将上面的对象原型方法||属性的创建方法哦了构造函数里面完成。具有更好的封装性。结果是一样的。 

function Person(name,age,job)
{//属性this.name=name;this.age=age;this.job=job;this.friends=["Jams","Martin"];//方法if(typeof this.sayName != "function"){Person.prototype.sayName=function(){alert(this.name);};Person.prototype.sayFriends=function(){alert(this.friends);};}
}var person = new Person("kevin",31,"SE");
person.sayName();
person.sayFriends();

另外还有两个创建对象的方法,寄生构造函数模式和稳妥构造函数模式。由于这两个函数不是特别常用,这里就不给出具体代码了。

写了这么多创建对象的方法,其实真正推荐用的也就是方法6和方法7。当然在真正开发中要根据实际需要进行选择,也许创建的对象根本不需要方法,也就没必要一定要选择它们了。

 

转载于:https://www.cnblogs.com/changyangzhe/p/5721968.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/260930.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 RMAN 同步数据库

使用 RMAN 同步数据库使用 RMAN 同步数据库一.概述二 操作步骤(一).把生产库置为归档模式(二).启动rman做数据库0级备份(三).修改生产库数据库到未归档(四).拷贝备份集到测试库(五).在测试库上的操作一.概述 因项目组遇…

js实现图片上传预览及进度条

js实现图片上传预览及进度条 原文js实现图片上传预览及进度条 最近在做图片上传的时候&#xff0c;由于产品设计的比较fashion&#xff0c;上网找了比较久还没有现成的&#xff0c;因此自己做了一个&#xff0c;实现的功能如下&#xff1a; 1&#xff1a;去除浏览器<input …

webapi文档描述-swagger

最近做的项目使用mvcwebapi&#xff0c;采取前后端分离的方式&#xff0c;后台提供API接口给前端开发人员。这个过程中遇到一个问题后台开发人员怎么提供接口说明文档给前端开发人员,最初打算使用word文档方式进行交流&#xff0c;实际操作中却很少动手去写。为了解决这个问题&…

《推荐系统实践》样章:如何利用用户标签数据

《推荐系统实践》样章&#xff1a;如何利用用户标签数据 推荐系统的目的是联系用户的兴趣和物品&#xff0c;这种联系需要依赖于不同的媒介。GroupLens在文章1中认为目前流行的推荐系统基本上通过三种方式来联系用户兴趣和物品。如图1所示&#xff0c;第一种方式是通过用户喜欢…

STM32 基于正电原子开发板,改换芯片为STM32F103R6,Proteus仿真的一些问题

最近在学STM32&#xff0c;网上收集了一些信息&#xff0c;最后用正点原子的开发板来学习。 MDK的配置请参考原子哥的资料&#xff0c;我主要的学习方法是参考原子哥的开发板与实验案例&#xff0c;改换不一样的芯片&#xff0c;也要做出的一样的效果。但在最基础的入门就遇到…

深入理解闭包系列第二篇——从执行环境角度看闭包

前面的话 本文从执行环境的角度来分析闭包&#xff0c;先用一张图开宗明义&#xff0c;然后根据图示内容对代码进行逐行说明&#xff0c;试图对闭包进行更直观的解释 图示 说明 下面按照代码执行流的顺序对该图示进行详细说明 function foo(){var a 2;function bar(){console.…

VS2017 调用Tesseract

最近在学tesseract&#xff0c;但遇到太多的问题是。 虽然网上有不少的方法&#xff0c;就算是按照tersseract&#xff0c;github上提供的方法也是编译不成功。 问题一大堆。不过我也想到了其它方法最张还是可以用了。 我有2个方法&#xff0c; 方法1, 1&#xff0c;先build t…

在windows上安装OpenCV

在windows上安装OpenCV&#xff0c;官方提供的教程&#xff0c;我翻译了一下。如有不正解&#xff0c;请指正 使用git-bash&#xff08;版本> 2.14.1&#xff09;和cmake&#xff08;版本> 3.9.1&#xff09;安装 1.您必须下载cmake&#xff08;版本> 3.9.1&…

CMake 编译 OpenCV 项目,不是编译OpenCV, 用了之后才知道CMake也太好用了。

新建一个 CMakeList.txt 复制下面代码&#xff0c;并保存 cmake_minimum_required (VERSION 3.0)PROJECT(Chapter2)set (CMAKE_CXX_STANDARD 11)IF(EXISTS ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)conan_basic_setup() E…

Java Ajax jsonp 跨域请求

2019独角兽企业重金招聘Python工程师标准>>> 1. 什么是JSONP 一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通&#xff0c;而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略&#xff0c;网页…

对IEnumerableT,IDictionaryTkey,TValue,ICollectionT,IListT的总结

1、IEnumerable<T>接口和IEnumerable接口 实现了IEnumerable接口的集合表明该集合能够提供一个enumerator(枚举器)对象&#xff0c;支持当前的遍历集合。IEnumerable接口只有一个成员GetEnumerator()方法。 IEnumerator接口实现了IEnumerator接口的集合实现了从一个元素到…

学习Python中用numpy与matplotlib遇到的一些数学函数与函数的绘图

学习Python中的一些数学函数与函数的绘图 主要用到numpy 与 matplotlib 如果有什么不正确&#xff0c;欢迎指教。 图片不知道怎样批量上传&#xff0c;一个一个怎么感觉很小&#xff0c;请见谅 自行复制拷贝&#xff0c;到vs&#xff0c;jupyter notebook, spyder都可以 函…

有这个OCR程序,不用再买VIP了,Python 调用百度OCR API

最近学习&#xff0c;很多东西都是视频&#xff0c;截图后&#xff0c;又想做成文档保存起来。 刚开始不多&#xff0c;打一下字就很快解决了。 随着时间的推移&#xff0c;现在越来越多的图了&#xff0c;管理起来确实不方便&#xff0c;打字有时也不能很快的解决。 所以就…

linux常用命令_Linux常用命令全称

从事IT行业的很多人都会使用Linux常用命令&#xff0c;但是知道这些常用命令全称的人并不多&#xff0c;让我们来看看这些常用命令对应的全称吧&#xff01;必备Linux命令和C语言基础_C语言_嵌入式开发工程师-创客学院​www.makeru.com.cnpwd:print work directory 打印当前目录…

存储程序(1)——MYSQL

MySQL支持把几种对象存放在服务器端供以后使用。这几种对象有一些可以根据情况通过程序代码调用&#xff0c;有一些会在数据表被修改时自动执行&#xff0c;还有一些可以在预定时刻自动执行。它们包括以下几种: 1.存储函数(stored function)。返回一个计算结果&#xff0c;该结…

闯过这 54 关,点亮你的 Git 技能树 (五) - 完结篇

这是一个系列文章&#xff0c;介绍学习 Git 的一个小游戏 - githug&#xff0c;如果你是第一次看到&#xff0c;请先阅读&#xff1a;闯过这 54 关&#xff0c;点亮你的 Git 技能树闯过这 54 关&#xff0c;点亮你的 Git 技能树&#xff08;一&#xff09;闯过这 54 关&#xf…

Jupyter notebook 不安装主题,通过修改css更改 默认字体,字体大小等

目标&#xff1a; Jupyter notebook 又不想改更主题的的情况下&#xff0c;可以通过修改css的目的来达到修改默认的字体&#xff0c;字号心达到可以好的阅读效果。 方法 要修改的css文件目录如下&#xff0c; D:\Anaconda\Lib\site-packages\notebook\static\custom 这个就是…

坚果nuts 加速 官网_【喂你播】坚果手机2020新品发布会来了;三星定向华为手机推以旧换新...

周五喂diu 不只有你们爱的女主播 还有小编呢BGM&#xff1a;Make You Hustle-Croatia Squad坚果手机2020新品发布会来了坚果手机正式宣布&#xff1a;坚果手机2020新品发布会将于10月20日19:30在五棵松M空间举行。根据此前爆料&#xff0c;坚果手机新品或命名为坚果Pro4&#x…

图像处理核函数:之高斯核的生成方法 python

图像处理核函数&#xff1a;之高斯核函数的生成方法 python高斯核函数&#xff08;低通高斯滤波器核&#xff09;高斯分布函数高斯核生成函数代码效果高斯核函数的图像高斯核函数&#xff08;低通高斯滤波器核&#xff09; 最近在看DIP&#xff08;Digital Image Processing)&…

WEB-INFO/lib build path 的jar包问题

为什么80%的码农都做不了架构师&#xff1f;>>> 一、build path&WEB-INFO/lib介绍 build path&#xff1a;可以说是引用&#xff1b; WEB-INFO/lib&#xff1a;可以说是固定在一个地方&#xff1b; eclipse编译项目的时候是根据build path的&#xff0c;如果…