Javascript创建对象几种方法解析
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();
- 与工厂模式对比,几点不同:没有现实的创建空对象;直接将属性和方法赋值给this;不需要return
- 通过New操作符创建Person对象的新实例:①创建一个新的对象 ②this指向这个新对象(作用域)③执行构造函数中的代码,对新对象添加属性和方法④返回新对象
- 通过instanceof检测对象类型,发现通过Person构造函数创建的对象,即使Person类的实例,又是Object对象的实例 - 创建自定义的构造函数表明可以将它的实例标识为一种特定的类型
alert(leo instanceof Person); //true
alert(leo instanceof Object); //true 所有对象都继承自Object
- 区分构造函数和普通函数
①. 任何函数通过new操作符调用,就可做为构造函数
②. 自定义的构造函数,不通过new调用,与普通函数没有区别
Person('window',100);//直接调用,相当于将Person类的属性方法直接添加到了this上
window.sayName(); //window
- 缺点:通过构造函数,每个方法都要在实例上重新创建一遍,每个实例的sayName方法,相当于执行
this.sayName = new Function("alert(this.name)")单独创建出来的
alert(leo.sayName==cherry.sayName);//false
原型模式:
- 创建的每个函数都有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();
- 只要创建一个新函数,就会为该函数创建一个prototype属性,这个属性指向原型对象。在我们创建的对象person1和person2中都包含一个内部属性,该属性指向Person.prototype,因此两个实例都可以调用原型中的sayName()方法。Object.getPrototypeOf()方法可以更方便的取得一个对象的原型.
alert(Person.prototype.isPrototypeOf(person1));//true
alert(Person.prototype.isPrototypeOf(person2));//true
alert(Object.getPrototypeOf(person1)==Object.getPrototypeOf(person2));//true
- 给一个对象添加一个属性,这个属性会屏蔽原型对象中存储的同名属性,通过hasOwnProperty()方法可判断是实例对象中的属性,还是原型中的属性;通过in运算符,可以判断在对象上能否找到某属性,而不区分是实例属性还是原型属性,for in循环中只会遍历可访问、可枚举的属性。
person1.name='Nancy';
alert(person1.name);//Nancy
alert(person1.hasOwnProperty("name"));//True 实例对象上的属性
alert(person2.hasOwnProperty("name"));//false 原型中的属性
alert("name" in person1);//true
alert("name" in person2);//true
for(key in person1){
alert(`${key}:${person1[key]}`)
}
- 原型模式的缺点:①缺少向构造函数传递初始化参数这一环节,使得同一个对象的所有实例在默认情况下都会取得相同的属性值。②在实例中修改引用属性的值,会影响其他的实例。
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, Cherry
alert(newPerson2.friends);//Leo, Cherry
newPerson1.friends.push('Mai');//friends属性引用数组在Newperson.prototype而非newPerson1中,newPerson1.friends和newPerson2.friends指向的是同一个引用
alert(newPerson1.friends);//Leo, Cherry, Mai
alert(newPerson2.friends);//Leo, Cherry, Mai
alert(newPerson1.friends === newPerson2.friends);//true
组合使用构造函数模式和原型模式
- 组合使用构造函数模式和原型模式是创建自定义类型的常见方式,构造函数用于定义实例属性,原型模式用于定义方法和共享属性。
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, Tony
alert(person2.friends);//Leo, Cherry, Melody
Javascript创建对象几种方法解析的更多相关文章
- 创建JAVASCRIPT对象3种方法
创建JAVASCRIPT对象3种方法 方法一:直接定义并创建对象实例 var obj = new Object(); //创建对象实例 //添加属性obj.num = 5; //添加属性 o ...
- ASP.NET,C#后台调用前台javascript的五种方法
C#后台调用前台javascript的五种方法 由于项目需要,用到其他项目组用VC开发的组件,在web后台代码无法访问这个组件,所以只好通过后台调用前台的javascript,从而操作这个组件.在网上 ...
- VC调用javascript的几种方法
第一种:通过execScript调用.这种方法,虽然操作方便,但不能获取返回值.m_spHtmlDoc->get_parentWindow(&m_pHtmlWindow);VARIANT ...
- Java/JSP获得客户端网卡MAC地址的三种方法解析
java/jsp获得客户端(IE)网卡MAC地址的方法大概有三种. 1.通过命令方式,在客户端执行Ipconfig 等等.(java/jsp) 2.通过ActiveX的方法.(jsp) 3.通过向13 ...
- C#后台调用前台javascript的五种方法小结
第一种,OnClientClick (vs2003不支持这个方法) <asp:Button ID="Button1" runat="server" Tex ...
- 【转】 C#后台调用前台javascript的五种方法
第一种,OnClientClick (vs2003不支持这个方法)<asp:ButtonID="Button1" runat="server" Te ...
- 四种方法解析JSON数据
(1)使用TouchJSon解析方法:(需导入包:#import "TouchJson/JSON/CJSONDeserializer.h") //使用TouchJson来解析北京的 ...
- JAVA 创建对象4种方法
java创建对象的几种方式 博客分类: java (1) 用new语句创建对象,这是最常见的创建对象的方法.(2) 运用反射手段,调用java.lang.Class或者java.lang.refl ...
- 网页中插入javascript的几种方法
网页中插入javascript的方法常见的有两种: 一.直接使用html标记 JavaScript 可以出现在 html的任意地方.使用标记<script>…</script> ...
随机推荐
- webpack 4.0 相关
Webpack 4.0发布了!! https://www.jianshu.com/p/3a13f1b37300 webpack详解 https://juejin.im/post/5aa3d2056fb ...
- idea打印gc日志
1.在idea里添加配置 -XX:+PrintGCDetails 2.打印GC的详细信息: -XX:+PrintGCDetails 解释:打印GC详细信息. -XX:+PrintGCTimeStamp ...
- ODBC数据管理器 SqlServer实时数据同步到MySql
---安装安装mysqlconnector http://www.mysql.com/products/connector/ /* 配置mysqlconnector ODBC数据管理器->系统D ...
- 前端基础jQuery
jQury jQuery 是一个 JavaScript 函数库,jQuery 极大地简化了 JavaScript 编程. jQuery库包含以下功能: HTML 元素选取 HTML 元素操作 CSS ...
- Poj 2594 Treasure Exploration (最小边覆盖+传递闭包)
题目链接: Poj 2594 Treasure Exploration 题目描述: 在外星上有n个点需要机器人去探险,有m条单向路径.问至少需要几个机器人才能遍历完所有的点,一个点可以被多个机器人经过 ...
- [ZPG TEST 111] 奶牛的新家【DP】
3.奶牛的新家 [问题描述] 由于奶牛们纷纷表示破旧的房子实在是太丑陋了,DD决定给他们建造新家.现在有许多奶牛决定将家建造在n*m的城市中.然而奶牛们分成了k帮派,不同帮派的奶牛不能住在同列或同行上 ...
- 题解报告:hdu 1228 A+B(字符串)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1228 Problem Description 读入两个小于100的正整数A和B,计算A+B. 需要注意 ...
- Codeforces Round #235 (Div. 2) D (dp)
以为是组合,后来看着像数位dp,又不知道怎么让它不重复用..然后就没思路 了. 其实状压就可以了 状压是可以确定一个数的使用顺序的 利用01也可以确定所有的数的使用以及不重复 dp[i+1<&l ...
- jsp中提示修改成功
修改成功提示 servert包 request.setAttribute("success", "修改失败"); 效果而 function f(){ var n ...
- SQL SERVER 事务例子
存储过程格式: CREATE PROCEDURE YourProcedure AS BEGIN SET NOCOUNT ON; BEGIN TRY---------------------开始捕捉异常 ...