一、对象创建

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 对象创建多种方式 原型链的更多相关文章

  1. JavaScript 变量、函数与原型链

    定义 || 赋值 1-函数的定义 函数定义的两种方式: “定义式”函数:function fn(){ alert("哟,哟!"); } “赋值式”函数:var fn = funct ...

  2. 理解类、对象、实例、原型链以及继承 - WPF特工队内部资料

    理解类.对象.实例.原型链以及继承 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...

  3. Java Object 对象创建的方式 [ 转载 ]

    Java Object 对象创建的方式 [ 转载 ] @author http://blog.csdn.net/mhmyqn/article/details/7943411 显式创建 有4种显式地创建 ...

  4. JavaScript对象创建的几种方式

    1 工厂模式 1.1 创建 function createFruit(name,colors) { var o = new Object(); o.name = name; o.colors = co ...

  5. 《JAVASCRIPT高级程序设计》根植于原型链的继承

    继承是面向对象的语言中,一个最为津津乐道并乐此不疲的话题之一.JAVASCRIPT中的继承,主要是依靠原型链来实现的.上一篇文章介绍过,JAVASCRIPT中,每一个对象都有一个prototype属性 ...

  6. JS对象创建常用方式及原理分析

    ====此文章是稍早前写的,本次属于文章迁移@2017.06.27==== 前言 俗话说"在js语言中,一切都对象",而且创建对象的方式也有很多种,所以今天我们做一下梳理 最简单的 ...

  7. JavaScript的面向对象原理之原型链详解

    一.引言 在16年的10月份,在校内双选会找前端实习的时候,hr问了一个问题:JavaScript的面向对象理解吗?我张口就说“JavaScript是基于原型的!”.然后就没什么好说的了,hr可能不知 ...

  8. JavaScript的面向对象原理之原型链

    二.JavaScript的对象 为了能够清楚的解释这一切,我先从对象讲起.从其他面向对象语言(如Java)而来的人可能认为在JS里的对象也是由类来实例化出来的,并且是由属性和方法组成的. 实际上在JS ...

  9. Javascript之其实我觉得原型链没有难的那么夸张!

    原型链.闭包.事件循环等,可以说是js中比较复杂的知识了,复杂的不是因为它的概念,而是因为它们本身都涉及到很多的知识体系.所以很难串联起来,有一个完整的思路.我最近想把js中有点意思的知识都总结整理一 ...

随机推荐

  1. UIButton 设置图片文字垂直居中排列

    #pragma mark 按钮图片文字垂直居中排列 -(void)setButtonContentCenter:(UIButton *)button { CGSize imgViewSize,titl ...

  2. c++课设学生成绩与学籍管理系统

    题目要求(手打,累):设计一个类CStudent,类中包含一个学生的基本数据如下: 编号,姓名,性别,年龄,数学成绩,计算机成绩,外语成绩. 并假设编号为整数,且从1号往后连续编码:姓名为字符串,性别 ...

  3. WIN8配置IIS8.0+PHP+Mysql+Zend

    第一步 开启WIN8的IIS 8.0  控制面板 → 程序与功能 → 启用或关闭WINDOWS功能 按照上面勾选 确定即可 成功安装完毕 打开  http://localhost/ 或者 http:/ ...

  4. DNSlog实现Mysql注入

    step1: 通过DNSlog盲注需要用到load_file()函数.show variables like '%secure%' 查看load_file()可以读取的磁盘. 1.当secure_fi ...

  5. Clover相关知识

    -f 重建驱动缓存 darkwake=4 有深度睡眠有关的设置,不懂 kext-dev-mode=1 启用第三方驱动,比较重要. dart=0 修复因开启 VT-d 导致系统启动时SMC五国错误,系统 ...

  6. vue组件中this和$el指向

    示例代码为element ui 源码的select组件源码 控制台输出: 结论: this指向组件的实例. $el指向当前组件的DOM元素.

  7. Bootstrap学习遇到的role属性--- 无障碍网页应用属性

    以前接触过Bootstrap,但也只是仅仅接触,现在重新学习下,今天看到一个例子中的属性有一个role, 查阅资料发现这个是--WAI-ARIA无障碍设计属性: 通俗说是该设计为了一些盲人,失聪,残疾 ...

  8. Homebrew -- mac 缺失包补充工具

    https://brew.sh/index_zh-cn.htmlhttps://brew.sh/ 非root权限下运行 # github 源代码 https://github.com/Homebrew ...

  9. CRC-32的原理和实现

    /* crc32.c -- compute the CRC-32 of a data stream * Copyright (C) 1995-2002 Mark Adler * For conditi ...

  10. oracle 查看表行数所占空间大小

    最新数据库空间有感觉捉急了,上次,删了些数据空了800+G,撑了一个多月,现在还有400+G,每天10G的增量,多少空间也感觉不够用啊. 不能加硬盘,就只有删数据了.. 删数据,人懒,直接找表行最多, ...