本文您将看到如下内容:数组
一句话说明什么是原型:原型就是一个JavaScript对象,原型能存储咱们的方法,构造函数建立出来的实例对象可以引用原型中的方法。浏览器
有以下代码服务器
function Foo(){ this.sayHello = function(){ } }
因为对象是调用new Foo()
所建立出来的,所以每个对象在建立的时候,函数 sayHello 都会呗建立一次闭包
那么有没一个对象都含有一个独立的,不一样的,可是功能逻辑同样的函数,好比:{} == {}
。框架
在代码中方法就会消耗性能,最典型的资源就越是内存函数
这里最好的方法就是将函数放在构造函数以外,那么在构造函数中引用该函数便可性能
function sayHello () {} function Foo () { this.say = sayHello; }
会在开发中变得困难:引入框架危险,代码繁冗很差维护。解决方法就是若是外面的函数不占用其名字,并且在函数名下。this
每个函数在定义的时候,有一个神秘对象(就是原型对象,暂且这么称呼)被建立出来。spa
每个由构造函数建立的对象都会默认的链接到该神秘对象上。prototype
var f1 = new Foo(); var f2 = new Foo(); f1.sayHello(); //若是f1没有sayHello那么就会在Foo.prototype中去找
由构造函数建立出来的众多对象共享一个对象就是:构造函数.prototype
只须要将共享的东西,重复会多占用内存的东西放到构造函数.prototype
中,那么全部的对象就能够共享了。
function Foo(){} Foo.prototype.sayHello = function(){ console.log("…."); } var f1 = new Foo(); f1.sayHello(); var f2 = new Foo(); f2.sayHello(); console.log(f1.sayHello === f2.sayHello); // true
类class:在JS中就是构造函数
实例(instance)与对象(object)
键值对与属性和方法
父类与子类(基类和派生类)
在JavaScript中,原型也是一个对象,经过原型能够实现对象的属性继承,JavaScript的对象中都包含了一个[[Prototype]]
内部属性,这个属性所对应的就是该对象的原型。
[[Prototype]]做为对象的内部属性,是不能被直接访问的。因此为了方便查看一个对象的原型,Firefox和Chrome中提供了__proto__
这个非标准(不是全部浏览器都支持)的访问器(ECMA引入了标准对象原型访问器"Object.getPrototype(object)")。
下面经过一个例子来看看原型相关概念:
function Person() {} // 神秘对象就是Person.prototype //那么只有使用构造函数才能够访问它 var o = new Person(); //之前不能直接使用o来访问神秘对象 //如今有了__proto__后, o.__proto__也能够直接访问神秘对象 //那么o.__proto__ === Person.prototype
神秘对象(原型)中都有一个属性constructor
,翻译为 构造器 。表示该原型是与什么构造函数联系起来的。
__proto__
有什么用?能够访问原型。因为在开发中除非特殊要求,不要使用实例去修改原型的成员,所以该属性开发时使用较少。可是在调试过程当中很是方便,能够轻易的访问原型进行查当作员
若是在早期的浏览器中使用实例须要访问原型如何处理?可使用实例对象访问构造器,而后使用构造器访问原型
var o = new Person(); o.constructor.prototype
若是给实例继承自原型的属性赋值
function Foo(); Foo.prototype.name = "test"; var o1 = new Foo(); var o2 = new Foo(); o1.name = "张三"; // 不是修改原型中的name而是本身增长了一个name属性 console.log(o1.name + ','+ o2.name); // 张三,test
对于以下代码:
function Person(){} var p = new Person() console.log(Person.prototype.constructor); //function Person(){} console.log(Person.prototype.constructor.name); //Person console.log(typeof Person.prototype.constructor); //function console.log(p.__prop__); console.log(p.__prop__ === Person.prototype);//true
因而他们的关系图以下:
凡是对象就有原型,原型也是对象。所以凡是给定一个对象,那么就能够找到他的原型,原型还有原型,那么如此下去,就构成一个对象的序列,称该结构为原型链。
问题:
凡是使用构造函数,建立出对象,而且没有利用赋值的方式修改原型,就说该对象保留默认的原型链。
默认原型链结构是什么样子呢?
function Person(){} var p = new Person(); //p 具备默认的原型链
默认的原型链结构就是:当前对象 -> 构造函数.prototype -> Object.prototype -> null
在实现继承的时候,有时候会利用替换原型链结构的方式实现原型继承,那么原型链结构就会发送改变
function DunizbCollection(){} DunizbCollection.prototype = []; var arr = new DunizbCollection(); // arr -> [] -> Array.prototype -> Object.prototype -> null
在JS中使用Function能够实例化函数对象 。也就是说在JS中函数与普通对象同样,也是一个对象类型。函数是JS中的一等公民。
要解决的问题
语法
new Function( arg0,arg1,arg1,….argN, body );
Function 中的参数所有是字符串
该构造函数的做用是将参数连接起来组成函数
举例:建立一个打印一句话的函数
// 传统的 function foo () { console.log( '你好' ); } //Function var func = new Function( 'console.log( "你好" );' ); // 功能上,这里foo 与 func 等价
再好比,建立一个空函数
//传统 function foo () {} //Function var func = new Function(); func();
传入函数内一个数字,打印该函数
//传统 function foo ( num ) { console.log( num ); } //Function var func = new Function( "num" ,"console.log( num )" ); func();
任意的一个函数,都是至关于Function的实例,相似于{}与new Object()的关系。
function foo () {}
上面的代告诉解析器,有一个对象叫foo,它是一个函数;至关于new Function()
获得一个函数对象
__proto__
对于Function,咱们还必须知道
Object做为对象是继承自Function.prototype的,又“Function.prototype”继承自Object.prototype
foo.prototype.__proto__ === Object.prototype // true
下面绘制出 Function 的构造原型实例三角形结构
Function是使用字符串构建函数,那么就能够在程序运行过程当中构建函数.
之前的函数必须一开始就写好,再通过预解析,一步一步的运行
假定从服务器里拿到“[1,2,3,4,5]”,将数组形式的字符串转换成数组对象
var arr = ( new Function( 'return ' + str + ' ;' ) )();
推荐阅读