javascript中创建对象的方式及优缺点(一)
1. 简单方式创建对象
// 字面量方式创建对象
var person1 = {
name: "xyc",
age: 23,
sayHi: function() {
console.log(name);
}
}; // Object方式创建对象
var person2 = new Object();
person2.name = "lxy";
person2.age = 18;
person2.sayHi = function() {
console.log(person2.name);
}
虽然Object构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码,如上面的代码,每创建一个类似的person对象,就会重复上面的写法,代码较为冗余
为了解决这个问题(代码重复),下面引入工厂模式 ==>
2. 工厂模式创建对象
function createPerson(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var person1 = createPerson("Nicholas", 29, "Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor");
通俗的解释:工厂模式就是利用了函数的封装调用,类比工厂材料==>成品的过程,完成入口参数==>对象的过程,函数可以无数次的生成,因此能够避免上面产生大量重复代码的情况。工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)
为解决这个问题(对象识别),下面引入构造函数模式
3. 构造函数创建对象
3.1 构造函数与普通函数的区别
- 命名规则:构造函数一般是首字母大写,普通函数遵照小驼峰式命名法
- 函数调用:
构造函数:
(1)new fn( )
(2)构造函数内部会创建一个新的对象,即f的实例
(3)函数内部的this指向 新创建的f的实例
(4)默认的返回值是f的实例
普通函数:
(1)fn( )
(2)在调用函数的内部不会创建新的对象
(3)函数内部的this指向调用函数的对象(如果没有对象调用,默认是window)
(4)返回值由return语句决定 构造函数的返回值:
有一个默认的返回值,新创建的对象(实例),当手动添加返回值后(return语句):
(1)返回值是基本数据类型-->真正的返回值还是那个新创建的对象(实例)
(2)返回值是复杂数据类型(对象)-->真正的返回值是这个对象function foo() {
var f2 = new foo2();
console.log(f2); // {a: 3}
console.log(this); // window
return true;
}
function foo2() {
console.log(this); // foo2类型的对象 不是foo2函数
return {a: 3};
}
var f1 = foo();
console.log(f1); // true
3.2 new 操作符作用
使用new操作符调用构造函数会经历下面几个步骤:
(1)创建一个以这个函数为原型的空对象.
(2)将函数的 prototype 赋值给对象的 proto 属性
(3)将对象作为函数的 this 传进去。如果有 return 出来东西是对象的话就直接返回 return 的内容,没有的话就返回创建的这个对象
function NewFunc(func){
var ret = {};
if (func.prototype !== null) {
ret.__proto__ = func.prototype;
}
var ret1 = func.apply(ret, Array.prototype.slice.call(arguments, 1));
if ((typeof ret1 === "object" || typeof ret1 === "function") && ret1 !== null) {
return ret1;
}
return ret;
}
普通函数的作用主要是封装作用,能够在作用域内多处调用而已
3.3 构造函数解决对象识别
创建自定义的构造函数意味着可以通过 instanceof 将它的实例标识为一种特定的类型
function Person(name,age,job){
this.name = name;
this.age = age;
this.sayHi = function(){
console.log(this.name);
}
}
var person1 = new Person('xyc', 23);
var person2 = new Person('lxy', 22);
console.log(person1 instanceof Person); //true
console.log(person2 instanceof Person); //true
console.log(person1 instanceof Object); //true 因为Person继承自Object,所以这里一样成立.
3.4 缺陷
构造函数创建对象的方式解决了代码重复和对象识别的问题,但是创建的对象中含有方法时,每实例化一个Person,就会产生一个方法,也就是一个对象,每个对象分别占据内存。因此,构造函数创建对象的方式存在内存大量占用的风险
利用原型共享的特性,下面引入原型模式
4. 原型创建对象
function Person(){}
Person.prototype = {
constructor: Person,
name : "Nicholas",
age : 29,
job : "Software Engineer",
friends : ["Shelby", "Court"],
sayName : function () {
alert(this.name);
}
};
var person1 = new Person();
var person2 = new Person();
person1.sayName(); //"Nicholas"
person2.sayName(); //"Nicholas"
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Court,Van"
alert(person2.friends); //"Shelby,Court,Van"
alert(person1.friends === person2.friends); //true
原型创建对象的方式将属性和方法都存在与原型中,也就是说,只要通过这种形式创建的对象都会共享这些属性和对象,相对于方法共享这是我们乐于看到的,但是属性共享让每个实例缺失了“个性”;另外对于引用类型的属性共享时,如上面的例子,多个实例对引用类型的操作会被篡改。
实例一般都要有属于自己的全部属性,这也决定了原型创建方式的局限性。下面引入非常经典的对象创建方式
5. 构造函数+原型创建对象(重点)
组合构造函数模式与原型模式:构造函数模式用于定义实力属性,而原型模式用于定义方法和共享的属性
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.friends = ["Shelby", "Court"];
}
Person.prototype = {
constructor : Person,
sayName : function(){
alert(this.name);
}
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Count,Van"
alert(person2.friends); //"Shelby,Count"
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName); //true
这种方式创建的实例对象,每个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度地节省了内存;另外,这种方式还支持相构造函数传递参数,解决了上面的各种问题!
6. Object.create(ES5)
在ES5之前,只能使用new来实现原型链集成。总而言之Object.create()和字面量对象应该替换new object()方法。
Object.create()可以接收两个参数:提供原型的对象,可选属性对象(这个对象包含对新创建对象的配置)。
var Car = {
drive: function (miles) {
return this.odometer += miles;
}
};
var tesla = Object.create(Car, {
'odometer': {
value: 0,
enumerable: true
}
));
//输出10
console.log(tesla.drive(10));
总结

javascript中创建对象的方式及优缺点(一)的更多相关文章
- javascript中创建对象的方式及优缺点(二)
一.工厂模式 流程: 定义一个函数,函数返回对象. 适用场景: 需要创建多个对象,都是Object类型. 优点:完成了返回一个对象的要求. 缺点: 对象没有一个具体的类型,无法通过constructo ...
- javascript中创建对象的方式总结
javascript中创建对象的方式总结 具体代码如下: //创建对象的方式: //创建方式一 var person=new Object(); person.name='jack'; person. ...
- javascript中各种继承方式的优缺点
javascript中实现继承的方式有很多种,一般都是通过原型链和构造函数来实现.下面对各种实现方式进行分析,总结各自的优缺点. 一 原型继承 let Super = functioin(name = ...
- JavaScript中创建对象的三种方式!
JavaScript中创建对象的三种方式! 第一种 利用对象字面量! // 创建对象的三种方式! // 1 对象字面量. var obj = { // 对象的属性和方法! name: 'lvhang' ...
- 深入理解JavaScript中创建对象模式的演变(原型)
深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...
- javascript中创建对象的几种不同方法
javascript中创建对象的几种不同方法 方法一:最直白的方式:字面量模式创建 <script> var person={ name:"小明", age:20, s ...
- javascript 中继承实现方式归纳
转载自:http://sentsin.com/web/1109.html 不同于基于类的编程语言,如 C++ 和 Java,javascript 中的继承方式是基于原型的.同时由于 javascrip ...
- javascript中创建对象和实现继承
# oo ##创建对象 1. 原型.构造函数.实例之间的关系 * 原型的construct->构造函数:调用isPrototypeOf(obj)方法可以判定和实例的关系: * 构造函数的pro ...
- JavaScript 常见创建对象的方式
JavaScript 有哪几种创建对象的方式? javascript创建对象简单的说,无非就是使用内置对象或各种自定义对象,当然还可以用JSON:但写法有很多种,也能混合使用. (1)对象字面量的方式 ...
随机推荐
- 查找担保圈-step3-获取担保圈路径
USE [test] GO /****** Object: StoredProcedure [dbo].[p01_get_group_path] Script Date: 2019/7/8 14:40 ...
- TCP/IP 物理层卷二 -- 交换技术
一.概念 交换技术是指各台主机之间.各通信设备之间或者主机和通信设备之间(简单理解:你的PC和我的PC之间.你的PC和我的路由器.路由器之间)为交换信息所采用的的数据格式和交换装置的方式. 二.交换技 ...
- servlet_filterj简介
Filter总结: 1):Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, ...
- Dasha and Photos CodeForces - 761F (前缀优化)
大意: 给定n*m初始字符矩阵, 有k个新矩阵, 第$i$个矩阵是由初始矩阵区间赋值得到的, 求选择一个新矩阵, 使得其余新矩阵到它距离和最小. 字符集比较小, 可以考虑每次区间覆盖对每个字符的贡献. ...
- Intellij IDEA 配置 Code Style
前言 昨天自说自话,闲扯了界面设计和代码规范.设计确实需要一些经验,也不一定能取悦所有人.而代码规范却是程序员所起码应当做到的,多人协作中,杂乱的代码就好像批阅潦草的作文,可读性极差. 然而这是个懒人 ...
- redis 学习(12)-- redis 发布订阅
redis 发布订阅 发布订阅模式中的角色 发布者(publisher) 订阅者(subscriber) 频道(channel) 如图所示: 发布者发布消息到频道,订阅了频道的订阅者可以收到消息,订阅 ...
- JS常见面试题总结-真实被问到的!
1.判断数据类型有几种方法 console.log(typeof 'abc') // string console.log(Object.prototype.toString.call('abc')) ...
- 跑满带宽的一款百度网盘下载工具 : PanDownload
下载地址 : 点击进入 官网上面也有介绍使用.在这里,我再说一下 下载之后,解压,运行,登录, 登录好之后,准备进行设置 重要:下载情况分以下三部分 下载内容 < 300M,选择`打包下载`,只 ...
- C# 过滤字典中的数据 并将过滤后的数据转成新的字典对象
Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("); dic. ...
- vim 搜索 向前,向后
vim 搜索可以是 / 或者 ?,前者是往下找,后者是往前找. 用 n 查找下一个的时候,就和这两个指令指定的方向相同.如果你想改变方向的话,比如想往下找,那么 / 完了直接回车就行了.表示再次使用上 ...