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中有点意思的知识都总结整理一 ...
随机推荐
- sFlow-rt安装部署
sFlow技术是一种以设备端口为基本单元的数据流随机采样的流量监控技术,不仅可以提供完整的第二层到第四层甚至全网范围内的实时流量信息,而且可以适应超大网络流量(如大于10Gbit/s)环境下的流量 ...
- Android.PackageManager
1. Apk的安装和更新过程是怎样的呢? Ref[1] 2. 在安装.apk程序包时, .so是如何选择并安装的? 这里的选择是指,是如何根据CPU_ABI和CPU_ABI2的值来选择合适的.so的. ...
- [Centos] ERROR: Could not find useradd in chroot, maybe the install failed?
[mockbuild at localhost ~]$ mock -r centos-5-x86_64-testdev.cfg initinitcleanprepThis may take a whi ...
- System.Runtime.InteropServices.COMException: 检索 COM 类工厂中 CLSID 为 {0002E510-0000-0000-C000-000000000046} 的组件时失败,原因是出现以下错误: 80040154
这个问题困恼我好几天了,今天终于解决. 开始我在网上左百度右google,都没搜到最终的解决方案,今天我把解决方案贴出来,以供大家分享! 网上有些是报80070005错误的,跟我这个80040154错 ...
- divinglaravel.com
https://divinglaravel.com/ 这是一个深入 laravel 的学习网站
- How to execute sudo command in remote host via SSH
Question: I have an interactive shell script, that at one place needs to ssh to another machine (Ubu ...
- sqli-labs:24,二次注入
二次排序注入 二次排序注入也称为存储型注入,就是将可能导致 sql 注入的字符先存入到数据库中,当再次调用这个恶意构造的字符时,就可以出发 sql 注入. 二次排序注入思路: 1. 黑客通过构造数据的 ...
- Clover相关知识
-f 重建驱动缓存 darkwake=4 有深度睡眠有关的设置,不懂 kext-dev-mode=1 启用第三方驱动,比较重要. dart=0 修复因开启 VT-d 导致系统启动时SMC五国错误,系统 ...
- Asterisk的type类型和身份认证
Asterisk的type类型和身份认证 转载:http://zeevli.blog.163.com/blog/static/119591610201111745012380/ 在Asterisk中对 ...
- 博客写作的Checklist
Checklist 1.不要发明术语. 2.不要使用指代不清的代词.如:我,他. 3.不要使用错误的承前省. 4.不要使用口语. 5.给出结论之前,先交代背景. 6.站立会议报告中应有燃尽图. 7.燃 ...