用js怎么获取一个属性在js原型和原型链链上

Javascript原型链 - CNode技术社区
自己理解的Javascript原型链,不对的地方还请指正
Javascript是一门通过原型链来实现继承的面向对象的动态语言。其原型链机制本身并不复杂,但是理解起来有些绕。本文试图理清原型链的相关知识,并尝试归并以便于理解记忆。
本文的所有代码均是在chrome的console中执行。
从一个简单的例子开始
首先我们使用object literal来创建一个对象:
var koly = {name:'koly'};
那么,什么叫object literal呢?先来看看literal的定义:
literal: taking words in their usual or most basic sense without metaphor or exaggeration: dreadful in its literal sense, full of dread.
literal就是指最简单最基本的语言表达,没有花哨,没有隐喻,没有夸张。所以object literal就是说最简单的没有花哨的创建object的形式。除了object literal外还有什么string literal,array literal等,这里就不描述了。
回到我们刚刚创建的对象koly,我们来执行几条代码:
koly.prototype
//undefined
koly.__proto__
//Object {}
上面注释的部分表示chrome console里面的输出。koly.prototype的结果是undefined,那么undefined是什么意思呢?看看MDN上的定义,既然提到了undefined,那就顺便对比以下null好了:
undefined: The global undefined property represents the primitive value undefined. It is one of JavaScript’s primitive types.
null: The value null is a JavaScript literal representing null or an “empty” value, i.e. no object value is present. It is one of JavaScript’s primitive values.
相同之处,两个都是primitive values。不同之处undefined是global property,而null是Javascript literal。关于两者的区别,对于没有声明的对象,其值为一个对象的值为null则表示该值已被声明,且被赋值为null,koly.one是undefined,而执行koly.one=null,才能将koly.one赋值为null。所以null表示的其实是一个值,是一个基本的literal。跟‘one’这个string literal是一样的。
说完了undefined和null,我们回到prototype和__proto__,前者输出了undefined,表示koly这个对象上并没有prototype这个属性。后者输出了一个非undefined,表示koly上面是有这个东西的。但是我们在定义koly这个对象的时候,并没有添加__proto__这个属性啊,它是什么呢?
The __proto__ property of Object.prototype is an accessor property (a getter function and a setter function) that exposes the internal [[Prototype]] (either an object or null) of the object through which it is accessed.
上面的大意就是说通过__proto__可以访问对象内部的[[Prototype]],这下好了,[[Prototype]]又是什么呢?
Following the ECMAScript standard, the notation someObject.[[Prototype]] is used to designate the prototype of someObject. This is equivalent to the JavaScript property proto (now deprecated). Since ECMAScript 6, the [[Prototype]] is accessed using the accessors Object.getPrototypeOf() and Object.setPrototypeOf().
上面的意思就是[[Prototype]]是ECMAScript定义的东西,它跟之前的__proto__是一样的。__proto__被deprecated了,现在提倡用[[Prototype]]。那么,[[Prototype]]就代表了对象的prototype。
综合以上的信息,总结来说就是,**通过访问一个对象的__proto__可以访问这个对象的prototype。**那么,koly.__proto__就是koly这个对象的原型。
那么,对象的原型(prototype)是什么?
Each object has an internal link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype. null, by definition, has no prototype, and acts as the final link in this prototype chain.
说,每一个对象内部都有一个指向另一个对象的链接,这个链接就叫这个对象的prototype。这个链接也是一个对象,也有自己的prototype,这个prototype指向另一个对象,这个对象也有自己的prototype,指向另一个对象。对象及对象间的指向就叫做原型链,这个链的终点是null,null没有prototype。
以刚刚的koly为例子:
koly这个对象的内部有一个prototype,我们可以使用__proto__来访问
koly.prototype指向另一个对象,这个对象也有自己的prototype,可以使用__proto__来访问
那么koly.prototype指向的对象是谁呢?
All objects in JavaScript are descended from O all objects inherit methods and properties from Object.prototype, although they may be overridden (except an Object with a null prototype, i.e. Object.create(null)).
上面说所有的对象都由Object派生而来,所有对象都从Object.prototype继承方法。koly是一个对象,该对象是从Object派生而来,继承了Object.prototype的方法。我们来看看koly.__proto__跟Object.prototype是什么关系。
koly.__proto__ === Object.prototype
// true
这里的结果true代表了什么呢?
我们得先搞清楚===意味着什么。Javascript里面对于Object,Array等类型是有引用存在的,比如var koly = {name:'koly'}中,koly就是一个引用,这个引用指向了{name:'koly'},这个引用也有自己的值(可能是一个地址之类的)。当我们在evaluate koly这个引用的时候,得到的结果是{name:'koly'}这个对象,而不是koly本身的值。===比较的是引用本身的值,而不是引用指向的那个对象。
var one = {name:'one'};
var anotherOne = {name:'one'};
one === anotherO
// false
anotherOne = // 这里将one本身的值赋给了anotherOne,可以想象为将one的地址赋给了anotherOne
one === anotherO
// true
所以===应用于两个对象,其返回为true的情况表示两个对象的引用其值一样。考虑到上面的koly.__proto__ === Object.prototype,那么我们可以想象一定有一步koly.__proto__ = Object.prototype。
那么Object.prototype是什么呢?Javascript里面全都是对象,那么它是Object的__proto__吗?
先回答第二个问题:
Object.prototype === Object.__proto__;
// false
第一个问题,我们首先看看Object是什么?
The Object constructor creates an object wrapper.
Object是一个&constructor&,那么&constructor&又是什么?举个例子:
// This is a generic default constructor class Default
function Default() {
constructor就是一个函数。那么Object也是一个函数,通过这个函数可以创建对象,比如:
// Called as a constructor
new Object([value])
当对一个函数使用new关键字的时候,我们就称这个函数为constructor,new出来的东西称为对象。
Javascript里面几乎所有东西都是对象,所以constructor也是对象,这个对象自然也可以有自己的属性,那么prototype就是Object这个constructor的一个属性。同时Object还有另外一个属性[[Prototype]],这个属性可以通过__proto__在chrome里面访问到。
到这里,都有点晕了。我们试着来理一下:
Javascript里面几乎所有东西都是对象
每一个对象都有一个[[Prototype]],在chrome里面可以使用__proto__来访问
constructor或者说函数都是对象,有[[Prototype]],同时也有另外一个属性prototype
koly.__proto__指向了Object.prototype
Object是一个constructor,同时也是一个对象,就是说Object本身也有__proto__
constructor是一个函数,只是在使用的时候不是直接调用,而是使用new,其结果是创建一个对象
null没有[[Prototype]]
有了对上面这些概念的理解,我们再来看看由koly引出的原型链:
koly.__proto__ === Object.
// true
Object.prototype.__proto__ === null
// true
上面就是koly的原型链,比较简单。我们再来看看Object的原型链:
Object.__proto__ === Function.
// true
Function.prototype.__proto__ === Object.
// true
Object.prototype.__proto__ ===
//true
上面的Object和Function都是constructor,就是函数。原型链的链条是由__proto__来实现的。在跟原型链的时候只需聚焦__proto__就行了,constructor的prototype只是一个会出现在原型链条里面的特殊对象。
constructor的prototype会在使用constructor创建对象的时候赋给该对象的__proto__。由于koly是通过Object这个constructor创建的,所以koly.__proto__也就指向了Object.prototype。
function Animal(){};
var aAnimal = new Animal();
aAnimal.__proto__ === Animal.
// true
Animal.prototype.__proto__ === Object.
Object.prototype.__proto__ ===
原型链有什么用?
先来看一段文字:
When trying to access a property of an object, the property will not only be sought on the object but on the prototype of the object, the prototype of the prototype, and so on until either a property with a matching name is found or the end of the prototype chain is reached.
就是说在访问一个对象的属性的时候,会首先在对象上找,找不到就去对象的[[Prototype]]上找,找不着就去[[Prototype]]的[[Prototype]]上找,如果最后找到Object.prototype还没找到,就是undefined了,因为Object.prototype.__proto__ === null了。举个例子koly.toString()怎么找的呢?先在koly本身找,没有,就去koly.__proto__(koly.__proto__ === Object.prototype)上找,这时候就发现找到了,就返回了。
原型链与继承
先看一段代码:
function Animal(){
this.species = 'Animal';
function Dog() {
this.type = 'Dog';
// Dog应该要继承Animal
Dog.prototype = new Animal();
Dog.prototype.constructor = D
var aDog = new Dog();
console.log(aDog.species);
// Animal
说到继承,就得知道父与子。子继承了父的或者属性或者方法。换句话说,子可以使用父的方法。放在[[Prototype]]及原型链的情况下,就是说子没有的方法,可以在原型链上找到,即子的[[Prototype]]指向了父的某个对象的prototype,至于为什么不是直接指向父的prototype,参见阮一峰的。
上面的代码有一句Dog.prototype.constructor=D,这个不设置constructor也没有太大问题,只要你不用,StackOverflow上有讨论:。
顺便说说这个constructor对象是什么,这个东西保存了对象的构造函数,比如:
var koly = {name:'koly'};
koly.constructor === O
// true
function Animal(){}
var a = new Animal();
a.constructor === A
// true
更多原型链
来看一个图:
箭头起点的对象的__proto__就是箭头终点的对象。
我觉得,理解原型链,一定要弄清楚的是函数对象和其他对象的区别,前者除了有__proto__之外,还有prototype,而这两个是不一样的东西。还有就是,函数对象的prototype会在创建对象的时候被赋给该对象的__proto__。
好了,就先到这里。
console.log(Function);
console.log(Function.prototype);
[Function: Function]
[Function]
这两个有什么区别?
chrome下面的输出:
// function Function() {[native code]}
Function.prototype
//function () {}
Function就是一个函数,这个函数用来创建function。Function.prototype是一个对象,这个对象由Function创建出来。看代码:
Function.prototype.constructor === Function
看完之后感觉好像学会了JS的《葵花宝典》
楼主神作,加油
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
积极向上,这小伙挺不错……
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
1&script type="text/javascript"&2 var&Person =&function&() { };3 var&p =&new&Person();4&/script&很简单的一段代码,我们看看这个new到底做了什么?我们可以把new的过程拆分成以下三部:1、var p={}; & &//初始化一个对象p2、p.__proto__ = Person.3、Person.call(p);//讲this的值赋给p关键在于第二步,我们来证明一下:1&script type="text/javascript"&2var&Person =&function&() { };3var&p =&new&Person();4alert(p.__proto__ === Person.prototype);5&/script&这段代码返回true。说明我们步骤2是正确的。我们在这里简单的说一下__proto__。每个对象都会在内部初始化一个__proto__属性,当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样一直找下去,也就是我们平时所说的原型链概念。按照标准,__proto__是不对外公开的,也就是说是个私有属性,(ie中对象的__proto__属性为undefined),但是firefox的引擎将他暴露出来成为一个共有的属性,我们可以对外访问和设置。我们看一下代码,为什么p可以访问Person的Say:1&script type="text/javascript"&2var&Person =&function&() { };3 Person.prototype.Say =&function&() {4 alert("Person say");5}6var&p =&new&Person();7p.Say();8&/script&首先new Person();可以得出p.__proto__=Person.prototype。当我们调用p.Say()时,首先p中没有Say这个属性,于是,他就需要到他的__proto__中去找,也就是Person.prototype,而我们在上面定义了Person.prototype.Say=function(){};于是,就找到了这个方法。更复杂的例子也是按照这个流程来推理,这也就是原型链的实现原理。最后,其实prototype只是一个假象,它在实现原型链中只是起到了一个辅助作用,换句话说,他只是在new的时候有一定的价值,而原型链的本质,其实是__proto__。
阅读(541)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'js中的原型链,prototype与__proto__的关系',
blogAbstract:'首先说一下new的过程先看一段代码:',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:3,
publishTime:4,
permalink:'blog/static/',
commentCount:1,
mainCommentCount:1,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'积极向上,这小伙挺不错……',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}JS中原型链,说简单也简单。
首先明确: 函数(Function)才有prototype属性,对象(除Object)拥有__proto__。
首先,我画了一张图。
所谓原型链,指的就是图中的proto这一条指针链!
原型链的顶层就是Object.prototype,而这个对象的是没有原型对象的。
可在chrome的控制台里面输入:
Object.__proto__
function Empty() {}
原型链,如此而已。
对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__proto__混淆,二来它们之间的各种指向实在有些复杂,其实市面上已经有非常多的文章在尝试说清楚,有一张所谓很经典的图,上面画了各种线条,一会连接这个一会连接那个,说实话我自己看得就非常头晕,更谈不上完全理解了。所以我自己也想尝试一下,看看能不能把原型中的重要知识点拆分出来,用最简单的图表形式说清楚。
我们知道原型是一个对象,其他对象可以通过它实现属性继承。但是尼玛除了prototype,又有一个__proto__是用来干嘛的?长那么像,让人怎么区分呢?它们都指向谁,那么混乱怎么记啊?原型链又是什么鬼?相信不少初学者甚至有一定经验的老鸟都不一定能完全说清楚,下面用三张简单的图,配合一些示例代码来理解一下。
一、prototype和__proto__的区别
var a = {};
console.log(a.prototype);
//undefined
console.log(a.__proto__);
//Object {}
var b = function(){}
console.log(b.prototype);
console.log(b.__proto__);
//function() {}
/*1、字面量方式*/
var a = {};
console.log(a.__proto__);
//Object {}
console.log(a.__proto__ === a.constructor.prototype); //true
/*2、构造器方式*/
var A = function(){};
var a = new A();
console.log(a.__proto__); //A {}
console.log(a.__proto__ === a.constructor.prototype); //true
/*3、Object.create()方式*/
var a1 = {a:1}
var a2 = Object.create(a1);
console.log(a2.__proto__); //Object {a: 1}
console.log(a.__proto__ === a.constructor.prototype); //false(此处即为图1中的例外情况)
var A = function(){};
var a = new A();
console.log(a.__proto__); //A {}(即构造器function A 的原型对象)
console.log(a.__proto__.__proto__); //Object {}(即构造器function Object 的原型对象)
console.log(a.__proto__.__proto__.__proto__); //null
这个是怎么一回事呢?要从运算符instanceof说起。
一、instanceof究竟是运算什么的?
我曾经简单理解instanceof只是检测一个对象是否是另个对象new出来的实例(例如var a = new Object(),a instanceof Object返回true),但实际instanceof的运算规则上比这个更复杂。
首先w3c上有官方解释(,有兴趣的同学可以去看看),但是一如既往地让人无法一目了然地看懂&&
知乎上有同学把这个解释翻译成人能读懂的语言(),看起来似乎明白一些了:
//假设instanceof运算符左边是L,右边是R
L instanceof R
//instanceof运算时,通过判断L的原型链上是否存在R.prototype
L.__proto__.__proto__ ..... === R.prototype ?
//如果存在返回true 否则返回false
注意:instanceof运算时会递归查找L的原型链,即L.__proto__.__proto__.__proto__.__proto__...直到找到了或者找到顶层为止。
所以一句话理解instanceof的运算规则为:
instanceof检测左侧的__proto__原型链上,是否存在右侧的prototype原型。
二、图解构造器Function和Object的关系
我们再配合代码来看一下就明白了:
//①构造器Function的构造器是它自身
Function.constructor=== F//true
//②构造器Object的构造器是Function(由此可知所有构造器的constructor都指向Function)
Object.constructor === F//true
//③构造器Function的__proto__是一个特殊的匿名函数function() {}
console.log(Function.__proto__);//function() {}
//④这个特殊的匿名函数的__proto__指向Object的prototype原型。
Function.__proto__.__proto__ === Object.prototype//true
//⑤Object的__proto__指向Function的prototype,也就是上面③中所述的特殊匿名函数
Object.__proto__ === Function.//true
Function.prototype === Function.__proto__;//true
三、当构造器Object和Function遇到instanceof
我们回过头来看第一部分那个&奇怪的现象&,从上面那个图中我们可以看到:
Function.__proto__.__proto__ === Object.//true
Object.__proto__ === Function.//true
所以再看回第一点中我们说的instanceof的运算规则,Function instanceof Object 和&Object instanceof Function运算的结果当然都是true啦!
如果看完以上,你还觉得上面的关系看晕了的话,只需要记住下面两个最重要的关系,其他关系就可以推导出来了:
1、所有的构造器的constructor都指向Function
2、Function的prototype指向一个特殊匿名函数,而这个特殊匿名函数的__proto__指向Object.prototype
至于prototype和__proto__的关系如何推导,可以参考我写的上一篇博客《》
本文尝试阐述Js中原型(prototype)、原型链(prototype chain)等概念及其作用机制。上一篇文章()介绍了Js中变量作用域的相关概念,实际上关注的一个核心问题是:&在执行当前这行代码时Js解释器可以获取哪些变量&,而原型与原型链实际上还是关于这一问题。
我们知道,在Js中一切皆为对象(Object),但是Js中并没有类(class);Js是基于原型(prototype-based)来实现的面向对象(OOP)的编程范式的,但并不是所有的对象都拥有prototype这一属性:
var&a = {};&
console.log(a.prototype);&&
var&b =&function(){};&
console.log(b.prototype);&&
var&c =&'Hello';&
console.log(c.prototype);&&
prototype是每个function定义时自带的属性,但是Js中function本身也是对象,我们先来看一下下面几个概念的差别:
1.&function、Function、Object和{}
function是Js的一个关键词,用于定义函数类型的变量,有两种语法形式:
function&f1(){&
&&console.log('This is function f1!');
typeof(f1);&&
var&f2 =&function(){&
&&console.log('This is function f2!');
typeof(f2);&&
如果用更加面向对象的方法来定义函数,可以用Function:
var&f3 =&new&Function("console.log('This is function f3!');");&
f3();&&&&&&&&
typeof(f3);&&
typeof(Function);&
实际上Function就是一个用于构造函数类型变量的类,或者说是函数类型实例的构造函数(constructor);与之相似有的Object或String、Number等,都是Js内置类型实例的构造函数。比较特殊的是Object,它用于生成对象类型,其简写形式为{}:
var&o1 =&new&Object();&
typeof(o1);&&&&&&
var&o2 = {};&
typeof(o2);&&&&&
typeof(Object);&
2.&prototype&VS&__proto__
清楚了上面的概念之后再来看prototype:
Each function has two properties:&length&and&prototype
prototype和length是每一个函数类型自带的两个属性,而其它非函数类型并没有(开头的例子已经说明),这一点之所以比较容易被忽略或误解,是因为所有类型的构造函数本身也是函数,所以它们自带了prototype属性:
console.log(Object.prototype);&&
console.log(Function.prototype);
console.log(String.prototype);&&
除了prototype之外,Js中的所有对象(undefined、null等特殊情况除外)都有一个内置的[[Prototype]]属性,指向它&父类&的prototype,这个内置属性在ECMA标准中并没有给出明确的获取方式,但是许多Js的实现(如Node、大部分浏览器等)都提供了一个__proto__属性来指代这一[[Prototype]],我们通过下面的例子来说明实例中的__proto__是如何指向构造函数的prototype的:
var&Person =&function(){};&
Person.prototype.type =&'Person';&
Person.prototype.maxAge = 100;
var&p =&new&Person();&
console.log(p.maxAge);&
p.name =&'rainy';
Person.prototype.constructor === P&&
p.__proto__ === Person.&&&&&&&&&
console.log(p.prototype);&&&&&&&&&&&&&&&&&
上面的代码示例可以用下图解释:
Person是一个函数类型的变量,因此自带了prototype属性,prototype属性中的constructor又指向Person本身;通过new关键字生成的Person类的实例p1,通过__proto__属性指向了Person的原型。这里的__proto__只是为了说明实例p1在内部实现的时候与父类之间存在的关联(指向父类的原型),在实际操作过程中实例可以直接通过.获取父类原型中的属性,从而实现了继承的功能。
清楚了prototype与__proto__的概念与关系之后我们会对&Js中一切皆为对象&这句话有更加深刻的理解。进而我们会想到,既然__proto__是(几乎)所有对象都内置的属性,而且指向父类的原型,那是不是意味着我们可以&逆流而上&一直找到源头呢?我们来看下面的例子:
var&Obj =&function(){};&
var&o =&new&Obj();&
o.__proto__ === Obj.&&
o.__proto__.constructor === O&
Obj.__proto__ === Function.&
Obj.__proto__.constructor === F&
Function.__proto__ === Function.&
Object.__proto__ === Object.&&&&&
Object.__proto__ === Function.&&&
Function.__proto__.constructor === F
Function.__proto__.__proto__;&&&&&&&&&&&&&&&
Function.__proto__.__proto__ === o.__proto__.__proto__;&
o.__proto__.__proto__.__proto__ ===&null;&&&
从上面的例子和图解可以看出,prototype对象也有__proto__属性,向上追溯一直到null。
new关键词的作用就是完成上图所示实例与父类原型之间关系的串接,并创建一个新的对象;instanceof关键词的作用也可以从上图中看出,实际上就是判断__proto__(以及__proto__.__proto__...)所指向是否父类的原型:
var&Obj =&function(){};&
var&o =&new&Obj();
o&instanceof&O&
o&instanceof&O&
o&instanceof&F&
o.__proto__ === Obj.&
o.__proto__.__proto__ === Object.&
o.__proto__.__proto__ === F&&
JS 面向对象之原型链
对象的原型链
只要是对象就有原型
原型也是对象
只要是对象就有原型, 并且原型也是对象, 因此只要定义了一个对象, 那么就可以找到他的原型, 如此反复, 就可以构成一个对象的序列, 这个结构就被成为原型链
原型链到哪里是一个头?
一个默认的原型链结构是什么样子的?
原型链结构对已知语法结构有什么修正?
原型链的结构
原型链继承就是利用就是修改原型链结构( 增加、删除、修改节点中的成员 ), 从而让实例对象可以使用整个原型链中的所有成员( 属性和方法 )
使用原型链继承必须满足属性搜索原则
属性搜索原则
所谓的属性搜索原则, 就是对象在访问属性与方法的时候, 首先在当前对象中查找
如果当前对象中存储在属性或方法, 停止查找, 直接使用该属性与方法
如果对象没有改成员, 那么再其原型对象中查找
如果原型对象含有该成员, 那么停止查找, 直接使用
如果原型还没有, 就到原型的原型中查找
如此往复, 直到直到 Object.prototype 还没有, 那么就返回 undefind.
如果是调用方法就包错, 该 xxxx 不是一个函数
原型链结构图
构造函数 对象原型链结构图function Person (){}; var p = new Person();
{} 对象原型链结构图
[] 数组原型链结构图
Object.prototype&对应的构造函数
div 对应的构造函数
div -& DivTag.prototype( 就是 o ) -& Object.prototype -& null
appendTo: function ( dom ) {
function DivTag() {}
DivTag.prototype =
var div = new DivTag();
函数的构造函数 Function
在 js 中 使用 Function 可以实例化函数对象. 也就是说在 js 中函数与普通对象一样, 也是一个对象类型( 非常特殊 )
函数是对象, 就可以使用对象的动态特性
函数是对象, 就有构造函数创建函数
函数是函数, 可以创建其他对象(函数的构造函数也是函数)
函数是唯一可以限定变量作用域的结构
函数是 Function 的实例
new Function( arg0, arg1, arg2, ..., argN, body );
Function 中的参数全部是字符串
该构造函数的作用是将 参数链接起来组成函数
如果参数只有一个, 那么表示函数体
如果参数有多个, 那么最后一个参数表示新函数体, 前面的所有参数表示新函数的参数
如果没有参数, 表示创建一个空函数
创建一个打印一句话的函数
创建一个空函数
传入函数内一个数字, 打印该数字
利用 Function 创建一个函数, 要求传入两个数字, 打印其和
var func = new Function( 'num1', 'num2', 'console.log( num1 + num2 );' );
练习: 利用 Function 创建一个函数, 要求允许函数调用时传入任意个数参数, 并且函数返回这些数字中最大的数字.练习: 利用 Function 创建一个求三个数中最大数的函数.
解决代码太长的办法:
利用 加法 连接字符串
var func = new Function( 'a', 'b', 'c',
'var res = a & b ? a :' +
'res = res & c ? res :' +
利用字符串特性( 刚学 )
function foo ( a, b, c ) {
var res = a & b ? a :
res = res & c ? res :
var func = new Function( 'a', 'b', 'c', 'return foo( a, b, c );' );
ES6 的语法( 少浏览器实现 )
使用 键盘左上角的 左单引号 表示可换行字符串的界定符
(最终)利用 DOM 的特性完成该方法
arguments 对象
arguments 是一个伪数组对象. 它表示在函数调用的过程中传入的所有参数的集合.在函数调用过程中没有规定参数的个数与类型, 因此函数调用就具有灵活的特性, 那么为了方便使用,在 每一个函数调用的过程中, 函数代码体内有一个默认的对象 arguments, 它存储着实际传入的所有参数.
js 中函数并没有规定必须如何传参
定义函数的时候不写参数, 一样可以调用时传递参数
定义的时候写了参数, 调用的时候可以不传参
定义的时候写了一参数, 调用的时候可以随意的传递多个而参数
在代码设计中, 如果需要函数带有任意个参数的时候, 一般就不带任何参数, 所有的 参数利用 arguments 来获取.一般的函数定义语法, 可以写成:
function foo (
利用 Function 创建一个函数, 要求允许函数调用时传入任意个数参数, 并且函数返回这些数字中最大的数字.
function foo ( ) {
练习: 利用 Function 写一个函数, 要求传入任意个数字 求和
函数的原型链结构
任意的一个函数, 都是相当于 Function 的实例. 类似于 {} 与 new Object() 的关系
function foo ()
函数有&__proto__&属性
函数的构造函数是 Function
函数应该继承自&Function.prototype
Fucntion.prototype&继承自&Object.protoype
构造函数有prototype, 实例对象才有__proto__指向原型, 构造函数的原型才有 constructor 指向构造函数
array instanceof Array判断 构造函数 Array 的原型 是否在 实例对象 array 的原型链存在
阅读(...) 评论()

我要回帖

更多关于 js原型链图解 的文章

 

随机推荐