首页 web前端 js教程 理解Javascript_06_理解对象的创建过程_javascript技巧

理解Javascript_06_理解对象的创建过程_javascript技巧

May 16, 2016 pm 06:18 PM
创建过程

简单的代码
我们先来看一段简单的代码:

复制代码 代码如下:

function HumanCloning(){
}
HumanCloning.prototype ={
name:'笨蛋的座右铭'
}
var clone01 = new HumanCloning();
alert(clone01.name);//'笨蛋的座右铭'
alert(clone01 instanceof HumanCloning);//true
HumanCloning.prototype = {};
alert(clone01.name);//'笨蛋的座右铭'
alert(clone01 instanceof HumanCloning);//false
var clone02 = new HumanCloning();
alert(clone02.name);//undefined
alert(clone02 instanceof HumanCloning);//true

复杂的理论
JS中只有函数对象(函数)具备类的概念,因此创建一个对象,必须使用函数对象。函数对象内部有[[Construct]]方法和[[Call]]方法,[[Construct]]用于构造对象,[[Call]]用于函数调用,只有使用new操作符时才触发[[Construct]]逻辑。注:在本例中HumanCloning这个自定义函数是一个函数对象,那么请问Object,String,Number等本地对象是函数对象吗?答案是肯定的,这是因为本地对象都可以看作是函数的派生类型,在这个意义上,可以将它们跟用户定义的函数等同看待。(与《理解Javascript_04_数据模型》中"内置数据类型"一节相呼应)
var obj=new Object(); 是使用内置的Object这个函数对象创建实例化对象obj。var obj={};和var obj=[];这种代码将由JS引擎触发Object和Array的构造过程。function fn(){}; var myObj=new fn();是使用用户定义的类型创建实例化对象。
注:关于函数对象的具体概念会在后续的文章中讲解,现在可以将"函数对象"简单的理解为"函数"的概念及可.

内部的实现
结合本例,函数对象为HumanCloning,函数对象创建的对象实例为clone01和clone02. 现在我们来看一下var clone01 = new HumanCloning();的实现细节(注:函数对象的[[Construct]]方法处理逻辑来负责实现对象的创建):
1. 创建一个build-in object对象obj并初始化
2. 如果HumanCloning.prototype是Object类型,则将clone01的内部[[Prototype]]设置为HumanCloning.prototype,否则clone01的[[Prototype]]将为其初始化值(即Object.prototype)
3. 将clone01作为this,使用args参数调用HumanCloning的内部[[Call]]方法
3.1 内部[[Call]]方法创建当前执行上下文(注:关于执行上下文,将在后续博文中讲解,在《Javascript提速_01_引用变量优化》一文中已有部分讲解》)
3.2 调用HumanCloning的函数体
3.3 销毁当前的执行上下文
3.4 返回HumanCloning函数体的返回值,如果HumanCloning的函数体没有返回值则返回undefined
4. 如果[[Call]]的返回值是Object类型,则返回这个值,否则返回obj
注意,如下代码为步骤1,步骤2和步骤3的代码解释:
复制代码 代码如下:

var clone01 = {};
//程序外部是无法访问[[prototype]]的,仅用于理解
//clone01.[[prototype]] = HumanCloning.prototype;
HumanCloning.call(clone01);

注意步骤2中, prototype指对象显示的prototype属性,而[[Prototype]]则代表对象内部Prototype属性(隐式的)。构成对象Prototype链的是内部隐式的[[Prototype]],而并非对象显示的prototype属性。显示的prototype只有在函数对象上才有意义,从上面的创建过程可以看到,函数的prototype被赋给派生对象隐式[[Prototype]]属性,这样根据Prototype规则,派生对象和函数的prototype对象之间才存在属性、方法的继承/共享关系。(即原型继承实现原理,正是《理解Javascript_05_原型继承原理》的内容)
注意步骤3.4中描述,让我们来看一个来自于怿飞的问题:
理解Javascript_06_理解对象的创建过程_javascript技巧

我想,现在回答这个问题,应该是易如反掌吧。

注:原文地址http://www.planabc.net/2008/02/20/javascript_new_function/

内存分析
理解Javascript_06_理解对象的创建过程_javascript技巧
一张简易的内存图,并引入的函数对象的概念,同样也解释了上面代码(相对来说图不是很严谨,但易于理解)。在此也引出了一个问题,instanceof的实现原理,想必大家也看出了一些苗头,instanceof的判断依赖于原型链,具体实现细节,请参见后续博文。
本地属性与继承属性
对象通过隐式Prototype链能够实现属性和方法的继承,但prototype也是一个普通对象,就是说它是一个普通的实例化的对象,而不是纯粹抽象的数据结构描述。所以就有了这个本地属性与继承属性的问题。
首先看一下设置对象属性时的处理过程。JS定义了一组attribute,用来描述对象的属性property,以表明属性property是否可以在JavaScript代码中设值、被for in枚举等。
obj.propName=value的赋值语句处理步骤如下:
1. 如果propName的attribute设置为不能设值,则返回
2. 如果obj.propName不存在,则为obj创建一个属性,名称为propName
3. 将obj.propName的值设为value
可以看到,设值过程并不会考虑Prototype链,道理很明显,obj的内部[[Prototype]]是一个实例化的对象,它不仅仅向obj共享属性,还可能向其它对象共享属性,修改它可能影响其它对象。
我们来看一个示例:

复制代码 代码如下:

function HumanCloning(){
}
HumanCloning.prototype ={
name:'笨蛋的座右铭'
}
var clone01 = new HumanCloning();
clone01.name = 'jxl';
alert(clone01.name);//jxl
var clone02 = new HumanCloning();
alert(clone02.name);//笨蛋的座右铭

结果很明确,对象的属性无法修改其原型中的同名属性,而只会自身创建一个同名属性并为其赋值。
参考。
http://www.jb51.net/article/25008.htm
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

在JavaScript中替换字符串字符 在JavaScript中替换字符串字符 Mar 11, 2025 am 12:07 AM

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

构建您自己的Ajax Web应用程序 构建您自己的Ajax Web应用程序 Mar 09, 2025 am 12:11 AM

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

10个JQuery Fun and Games插件 10个JQuery Fun and Games插件 Mar 08, 2025 am 12:42 AM

10款趣味横生的jQuery游戏插件,让您的网站更具吸引力,提升用户粘性!虽然Flash仍然是开发休闲网页游戏的最佳软件,但jQuery也能创造出令人惊喜的效果,虽然无法与纯动作Flash游戏媲美,但在某些情况下,您也能在浏览器中获得意想不到的乐趣。 jQuery井字棋游戏 游戏编程的“Hello world”,现在有了jQuery版本。 源码 jQuery疯狂填词游戏 这是一个填空游戏,由于不知道单词的上下文,可能会产生一些古怪的结果。 源码 jQuery扫雷游戏

如何创建和发布自己的JavaScript库? 如何创建和发布自己的JavaScript库? Mar 18, 2025 pm 03:12 PM

文章讨论了创建,发布和维护JavaScript库,专注于计划,开发,测试,文档和促销策略。

jQuery视差教程 - 动画标题背景 jQuery视差教程 - 动画标题背景 Mar 08, 2025 am 12:39 AM

本教程演示了如何使用jQuery创建迷人的视差背景效果。 我们将构建一个带有分层图像的标题横幅,从而创造出令人惊叹的视觉深度。 更新的插件可与JQuery 1.6.4及更高版本一起使用。 下载

如何在浏览器中优化JavaScript代码以进行性能? 如何在浏览器中优化JavaScript代码以进行性能? Mar 18, 2025 pm 03:14 PM

本文讨论了在浏览器中优化JavaScript性能的策略,重点是减少执行时间并最大程度地减少对页面负载速度的影响。

Matter.js入门:简介 Matter.js入门:简介 Mar 08, 2025 am 12:53 AM

Matter.js是一个用JavaScript编写的2D刚体物理引擎。此库可以帮助您轻松地在浏览器中模拟2D物理。它提供了许多功能,例如创建刚体并为其分配质量、面积或密度等物理属性的能力。您还可以模拟不同类型的碰撞和力,例如重力摩擦力。 Matter.js支持所有主流浏览器。此外,它也适用于移动设备,因为它可以检测触摸并具有响应能力。所有这些功能都使其值得您投入时间学习如何使用该引擎,因为这样您就可以轻松创建基于物理的2D游戏或模拟。在本教程中,我将介绍此库的基础知识,包括其安装和用法,并提供一

使用jQuery和Ajax自动刷新DIV内容 使用jQuery和Ajax自动刷新DIV内容 Mar 08, 2025 am 12:58 AM

本文演示了如何使用jQuery和ajax自动每5秒自动刷新DIV的内容。 该示例从RSS提要中获取并显示了最新的博客文章以及最后的刷新时间戳。 加载图像是选择

See all articles