• javascript对象创建过程

    函数对象创建: JavaScript中定义函数,或者调用Function创建函数时,最终都会以类似这样的形式调用Function函 数:var newFun=Function(funArgs, funBody); 创建函数对象的主要步骤如下: 1. 创建一个build-in object对象fn 2. 将fn的内部[[Prototype]]设为Function.prototype 3. 设置内部的[[Call]]属性,它是内部实现的一个方法 4. 设置内部的[[Construct]]属性,它是内部实现的一个方法, 5. 设置fn.length为funArgs.length,如果函数没有参数,则将fn.length设置为0 6. 使用new Object()同样的逻辑创建一个Object对象fnProto 7. 将fnProto.constructor设为fn 8. 将fn.prototype设为fnProto 9. 返回fn 步骤1跟步骤6的区别为,步骤1只是创建内部用来实现Object对象的数据结构(build-in object structure),并完成内部必要的初始化工作,但它的[[Prototype]]、[[Call]]、[[Construct]]等属性 应当为null或者内部初始化值,即我们可以理解为不指向任何对象(对[[Prototype]]这样的属性而 言),或者不包含任何处理(对[[Call]]、[[Construct]]这样的方法而言)。步骤6则将按照前面描述的 对象创建过程创建一个新的对象,它的[[Prototype]]等被设置了。 从上面的处理步骤可以了解,任何时候我们定义一个函数,它的prototype是一个Object实例,这样默 认情况下我们创建自定义函数的实例对象时,它们的Prototype链将指向Object.prototype。 chrome下例子: function fn(args){return args;} fn.__proto__ === Function.prototype //chrome下为:function Empty() {} fn.prototype.constructor === fn 对象创建过程: JS中只有函数对象具备类的概念,因此要创建一个对象,必须使用函数对象。函数对象内部有 [[Construct]]方法和[[Call]]方法,[[Construct]]用于构造对象,[[Call]]用于函数调用,只有使用 new操作符时才触发[[Construct]]逻辑。 var obj=new Object(); 是使用内置的Object这个函数对象创建实例化对象obj。var obj={};和var obj=[];这种代码将由JS引擎触发Object和Array的构造过程。function fn(){}; var myObj=new fn(); 是使用用户定义的类型创建实例化对象。 new Fn(args)的创建过程如下: 1. 创建一个build-in object对象obj并初始化 2. 如果Fn.prototype是Object类型,则将obj的内部[[Prototype]]设置为Fn.prototype,否则obj的 [[Prototype]]将为其初始化值(即Object.prototype) 3. 将obj作为this,使用args参数调用Fn的内部[[Call]]方法 3.1 内部[[Call]]方法创建当前执行上下文 3.2 调用F的函数体 3.3 销毁当前的执行上下文 3.4 返回F函数体的返回值,如果F的函数体没有返回值则返回undefined 4. 如果[[Call]]的返回值是Object类型,则返回这个值,否则返回obj 函数的prototype被赋给派生对象隐式[[Prototype]]属性,这样根据Prototype规则,派生对象和函数 的prototype对象之间才存在属性、方法的继承/共享关系。

    0
  • fn.prototype是什么

    function fn(){} console.info(fn.prototype)是什么

    0
  • 原型链

    由于所有对象都有原型,而原型本身也是对象,所以原型也可能有原型,这样就构成了所谓的原型链。 原型链终止于链中原型为 null 的对象。Object 构造函数的默认原型就有一个 null 原型

    console.info(Object) console.info(Object.__proto__) console.info(Object.__proto__.__proto__) console.info(Object.__proto__.__proto__.__proto__) 返回值: function Object() { [native code] } function Empty() {} Object{} null

    0
  • Javascript的原型对象和prototype属性

    Javascript中的继承机制是所谓的原型对象继承,通过属性访问机制的特殊性来实现继承的。 模拟创建对象: 用new操作符创建对象的时候javascript会做3件事: 首先是创建一个空对象(empty object), 然后对这个空对象的原型对象进行赋值, 最后把这个空对象赋值给构造函数的this属性且运行这个构造函数。 function Person(name) { this.name = name; } var p = new Person(); 相当于以下步骤: 1. var p = {}; 2. p.[[prototype]] = Person.prototype //这一步是伪代码,实际上一个对象的原型对象是不能通 过代码来访问的, 3. p.methodName = Person ; //这样的话Person的this就会指向p p.methodName(); 创建完一个空对象后,会初始化这个空对象的原型对象,javascript会把构造函数的一个叫做 prototype的属性所指向的对象赋值给当前空对象的原型对象。所有的function都有一个prototype属 性,当一个function被定义之后这个属性会被自动的创建和初始化。一个function 的prototype属性的 初始值是一个对象(an object),这个对象只有一个属性叫做constructor,而这个constructor 的值 就是当前这个函数(或者叫构造函数)。 function Person(name) { this.name = name; } Person === Person.prototype.constructor; //true 总结: 1. 所有的对象都有原型对象,但不是每个对象都有prototype属性。 2. prototype属性是函数(function)特有的属性。 3.函数(function)也是一个对象,那么它也有原型对象,它的原型对象和它的prototype属性没有任 何关系。 4.一个函数的原型对象是Function.prototype所指向的那个对象。因为所有的function都是Function的 实例,Function是所有funciton的构造函数,按照上面的定义,一个对象的原型对象是这个对象的构造 函数的prototype所指的那个对象。 function Person(name) { this.name = name; } var p = new Person(“Marry”); p 的原型对象是Person.prototype Person 的原型对象是Function.prototype Person.prototype.constructor === Person //true 继承的例子: function Person(name){ this.name = name; } Person.prototype.walk = function () { alert(“walking”); } function Author(){ } 现在有了Author,想要用Author创建出来的对象继承Person那么就把Author的prototype属性重新赋值 为一个Person对象 Author.prototype = new Person(); 然后赋值之后原来的Author.prototype.constructor 就不是原来的Author 所以还要 Author.prototype.construtor = Author

    0
  • prototype与[[prototype]]的区别

    Function 对象的prototype只是一个属性,而所有对象都有[[prototype]]是一个内部属性,记做 [[prototype]]。 内部属性是不能访问的,某些实现,如SpiderMonkey和JavaScriptCore,会有一个__proto__属性,基本上 可以看成是[[prototype]]。 对于function f来说,new f()所产生的新对象,其内建属性[[prototype]]的值会被赋值为f.prototype的 值。 __proto__属性是一个对象,则它也有__proto__,这样就构成了prototype链。 x.isPrototypeOf(y)可以检测x是否是y的prototype链上的一环。 严格的说,(根据ECMA-262规范),所有函数初始化后,都有一个prototype属性,其值为new Object()。

    0
  • 一个坑爹的问题

    var a = {n:1}; a.x = a = {n:2}; alert(a.x); // --> undefined
    var a = { s: function(){alert('ok');} }; var b = { s: a.s }; a.s = function(){ alert('ok2') }; b.s();

    0
  • js return闭包理解

    <html> <head> <script type="text/javascript"> window.onload = function(){ (function test() { var i; for (i = 0; i < 5; i += 1) { document.getElementById("e"+i).onclick = function (i) { return function () { alert(i); }; }(i); } })(); var myObject = function ( ) { var value = 0; return { increment: function (inc) { value += typeof inc === 'number' ? inc : 1; }, getValue: function ( ) { return value; } } }( ); alert(myObject.getValue()); } </script> </head> <body> <div id="e0">e0</div> <div id="e1">e1</div> <div id="e2">e2</div> <div id="e3">e3</div> <div id="e4">e4</div> </body> </html>
    闭包的两个特点: 1、作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态。 2、一个闭包就是当一个函数返回时,一个没有释放资源的栈区。

    0
  • javascript堆和栈

    在ECMAScript中,变量可以存放两种类型的值,即原始值和引用值。 原始值指的就是代表原始数据类型(基本数据类型)的值,即Undefined,Null,Number,String,Boolean类 型所表示的值。 引用值指的就是复合数据类型的值,即Object,Function,Array,以及自定义对象,等等 原始值和引用值在内存分配中有什么不同

    0

赞助