Javascript 对象创建多种方式 原型链
一、对象创建
1、new Object 方式
直接赋上属性和方法
var obj = new Object();
obj.name = '娃娃';
obj.showName = function(){
alert(obj.name);
}
//调用
obj.showName();
缺点:每次使用都要写同样的代码,不能重用
2、工厂方法方式
把同样的代码封装在一个函数方法里,是对1、改进,减少重复代码。
function CreatePerson(name){
var obj = new Object(); //原料
obj.name = name; //加工
obj.showName = function(){
alert(this.name);
}
return obj;//出厂
}
var p1 = CreatePerson('哇哇');
p1.showName();
var p2 = CreatePerson('哈哈');
p2.showName();
//其实就是简单的封装函数,整个过程像工厂的流水线,所以叫工厂方式
缺点:无法识别创建的对象的类型。因为全部都是Object,没有区分度,不像Date、Array等,因此出现了构造函数模式。
3、构造函数方式
函数名首字母大写,这是为了和普通函数区分,而且有this指针。
function CreatePerson(name){
this.name = name;
this.showName = function(){
alert(this.name);
}
}
var p1 = new CreatePerson('娃娃');
p1.showName();
var p2 = new CreatePerson('哈哈');
p2.showName();
构造函数本身也是普通函数,取决于使用的方式,可以new(当作构造函数),也可以直接调用(当作普通函数),两者区别是this指针指向不一样。
new CreatePerson('haha'); //CreatePerson
CreatePerson('haha'); //window
new 内部操作
function CreatePerson(name){
var obj = {}; //声明一个空对象obj
obj._proto_= CreatePerson.prototype;
//把这个对象的_proto_属性指向构造函数的原型对象,这样obj就可以调用CreatePerson原型对象下的所有方法 。
CreatePerson.apply(obj); //用apply方法让this指向obj对象
this.name = name; //obj对象添加属性,方法
this.showName = function(){
alert(this.name);
};
return obj;//返回这个对象
}
缺点:可见这两个对象并不是共用一个方法,每new一次,系统都会新创建一个内存,这两个对象各自有各自的地盘,但他们具有相同的功能,还不共用。
alert(p1.showName==p2.showName);//false
4、原型+构造函数方式 最优方式
原型:
每个函数都有一个prototype属性,它是一个对象,也称作原型对象,我们可以把方法和属性写在它上面(不过原型对象不仅仅有我们写的属性和方法,还有别的),设计时概念。
而通过这个函数创建出来的实例对象,都能共享这个原型对象下的方法和属性。
编写方法:
把共享的属性和方法定义在函数的prototype下,不共享的内容通过构造函数来创建。
function CreatePerson(name){
//定义不共享内容
this.name = name;
}
//定义共享内容
CreatePerson.prototype.showName = function(){
alert(this.name);
}
var p1 =new CreatePerson('娃娃');
p1.showName();
var p2 = new CreatePerson('哈哈');
p2.showName();
alert(p1.showName==p2.showName);//true
由此也可以看出,showName()方法是共享的,也就是说他们共用一个内存,更进一步的说它们存在引用关系,也就是说你更改了p1的showName也会影响p2的showName。
_proto_属性:
运行时属性,每个实例化对象都有_proto_属性,它是一个指针,指向函数的prototype(设计时属性),保存了函数的prototype的地址,通过该_proto_属性可以让同一构造函数的多个实例对象能共享这个构造函数的prototype(设计时定义)下的方法和属性。
js中任何对象的值都是保存在堆内存中,我们声明的变量只是一个指针,保存了这个对象的实际地址,所以有了地址就能找到对象。
所以,_proto_属性实际就是实例化对象和原型对象之间的连接。
二、原型链
每个函数都可以成为构造函数,每个函数都有原型对象,每个原型对象也可以是一个实例化对象。
创建了构造函数Function的实例化对象fun,而Function的原型对象(Function.prototype),又是Object的实例对象,根据前边介绍,fun有个_proto_属性,指向了Function.prototype,而Function.prototype(是Object的实例对象)又指向了Object.prototype。
所以,通过_proto_属性,就形成了一条原型链。每个实例化对象都可以访问到链子上方的方法和属性,所以fun是可以访问Object原型对象下的方法和属性的。实际上所有对象都可以访问到Object的原型对象。
function Aaa(){}
Aaa.prototype.num = 3;
var a1 = new Aaa();
a1.num =10;
alert(a1.num); //

Javascript 对象创建多种方式 原型链的更多相关文章
- JavaScript 变量、函数与原型链
定义 || 赋值 1-函数的定义 函数定义的两种方式: “定义式”函数:function fn(){ alert("哟,哟!"); } “赋值式”函数:var fn = funct ...
- 理解类、对象、实例、原型链以及继承 - WPF特工队内部资料
理解类.对象.实例.原型链以及继承 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...
- Java Object 对象创建的方式 [ 转载 ]
Java Object 对象创建的方式 [ 转载 ] @author http://blog.csdn.net/mhmyqn/article/details/7943411 显式创建 有4种显式地创建 ...
- JavaScript对象创建的几种方式
1 工厂模式 1.1 创建 function createFruit(name,colors) { var o = new Object(); o.name = name; o.colors = co ...
- 《JAVASCRIPT高级程序设计》根植于原型链的继承
继承是面向对象的语言中,一个最为津津乐道并乐此不疲的话题之一.JAVASCRIPT中的继承,主要是依靠原型链来实现的.上一篇文章介绍过,JAVASCRIPT中,每一个对象都有一个prototype属性 ...
- JS对象创建常用方式及原理分析
====此文章是稍早前写的,本次属于文章迁移@2017.06.27==== 前言 俗话说"在js语言中,一切都对象",而且创建对象的方式也有很多种,所以今天我们做一下梳理 最简单的 ...
- JavaScript的面向对象原理之原型链详解
一.引言 在16年的10月份,在校内双选会找前端实习的时候,hr问了一个问题:JavaScript的面向对象理解吗?我张口就说“JavaScript是基于原型的!”.然后就没什么好说的了,hr可能不知 ...
- JavaScript的面向对象原理之原型链
二.JavaScript的对象 为了能够清楚的解释这一切,我先从对象讲起.从其他面向对象语言(如Java)而来的人可能认为在JS里的对象也是由类来实例化出来的,并且是由属性和方法组成的. 实际上在JS ...
- Javascript之其实我觉得原型链没有难的那么夸张!
原型链.闭包.事件循环等,可以说是js中比较复杂的知识了,复杂的不是因为它的概念,而是因为它们本身都涉及到很多的知识体系.所以很难串联起来,有一个完整的思路.我最近想把js中有点意思的知识都总结整理一 ...
随机推荐
- h5 微信分享朋友和朋友圈
生成JS-SDK权限验证签名 实现发送给朋友和分享到朋友圈时内容参数自定义 一.微信JS-SDK 1. 获得Access Token access token的获得方法在前面有介绍,详情见 微信公众平 ...
- BZOJ1855 股票交易 单调队列优化 DP
描述 某位蒟佬要买股票, 他神奇地能够预测接下来 T 天的 每天的股票购买价格 ap, 股票出售价格 bp, 以及某日购买股票的上限 as, 某日出售股票上限 bs, 并且每次股票交 ♂ 易 ( 购 ...
- a label can only be part of statement and a declaratioin is not a statement
参考资料: https://stackoverflow.com/questions/18496282/why-do-i-get-a-label-can-only-be-part-of-a-statem ...
- mysql 压缩版安装
环境介绍:win2008_x64+mysql5.7.10 64位 1.将压缩包解压到d:\\mysql目录,并将mysql目录中的my-default.ini 重命名为my.ini 2.将my.in ...
- tomcat探索
双击apache-tomcat-7.0.64.exe,一路默认点. 静态页路径 C:\Program Files\Apache Software Foundation\Tomcat 7.0\webap ...
- Linux学习笔记:JDK安装
系统为CentOS 7,安装Oracle jdk1.8 卸载系统自带的Openjdk(若无可跳过这一步,可以通过 java -version 查看),步骤是:查找Openjdk,卸载Openjdk r ...
- 【算法】BFS+哈希解决八数码问题
15拼图已经有超过100年; 即使你不叫这个名字知道的话,你已经看到了.它被构造成具有15滑动砖,每一个从1到15上,并且所有包装成4乘4帧与一个瓦块丢失.让我们把丢失的瓷砖“X”; 拼图的目的是安排 ...
- Django框架之序列化和上传文件
一.Django的序列化(对于ajax请求) Django中的序列化主要应用在将数据库中检索的数据返回给客户端用户,特别的Ajax请求一般返回的为Json格式. 1)django序列化的使用方法 . ...
- linux_磁盘挂载
mount -o loop 磁盘的位置 想要挂载的位置 磁盘卸载 umont 挂载的磁盘的详细位置 注意:磁盘卸载时你当前所在的路径不要在磁盘挂载的路径,应该其他与磁盘挂载路径不相干的路径下即可
- 检测鼠标是否在UI上unity
public static bool IsCursorOnUI(int inputID=-1){ EventSystem eventSystem = EventSystem.current; retu ...