变量对象,作用域链,闭包,匿名函数,this关键字,原型链,构造器,js预编译,对象模型,执行模型,prototype继承

想在js方面的水平有更进一步的提升,变量对象,作用域链,闭包,匿名函数,this关键字,原型链,构造器,js预编译,对象模型,执行模型,prototype继承这些概念肯定会经常碰到。

这么多的概念,有点晕了吧。这里抓取几个关键字,讲故事 一样把这些概念给串起来。

首先来看下对象的创建过程和函数对象的创建过程:

对象创建过程:

对象需要通过函数对象来创建。相当于java,c++语言通过类的构造函数创建。这里函数对象充当了类和构造函数的作用。

new Fn(args)的创建过程如下:

1,创建一个built-in object对象obj并初始化;

2,根据Fn.prototype属性的类型给obj的[[prototype]]赋值。如果Fn.prototype为Object类型,则obj的[[prototype]]设置为Fn.prototype,否则为obj的初始化值(Object.prototype)。

3,将obj作为this,使用args参数来调用Fn内部[[call]]方法;

  3.1 内部[[call]]方法创建当前执行上下文

  3.2 调用Fn的函数体

  3.3 销毁当前的执行上下文

  3.4 返回Fn的返回值,如果没有返回则返回undefined

4,如果[[call]]的返回值是object,则返回这个值,否则返回obj;

tip:

1,每个对象都有一个隐式的[[prototype]]内部属性,每一个函数对象都有一个显式的prototype属性。

demo:

var Person = function () { };
Person.prototype.Say = function () {
alert("Person say");
}
Person.prototype.Salary = 50000;
var Programmer = function () { };
Programmer.prototype = new Person();
Programmer.prototype.WriteCode = function () {
alert("programmer writes code");
};
Programmer.prototype.Salary = 500;
var p = new Programmer();
p.Say();
p.WriteCode();
alert(p.Salary);  

我们来做这样的推导:

var p=new Programmer()可以得出p.__proto__=Programmer.prototype;

而在上面我们指定了Programmer.prototype=new Person();我们来这样拆分,var p1=new Person();Programmer.prototype=p1;那么:

p1.__proto__=Person.prototype;

Programmer.prototype.__proto__=Person.prototype;

由根据上面得到p.__proto__=Programmer.prototype。可以得到p.__proto__.__proto__=Person.prototype。

好,算清楚了之后我们来看上面的结果,p.Say()。由于p没有Say这个属性,于是去p.__proto__,也就是Programmer.prototype,也就是p1中去找,由于p1中也没有Say,那就去p.__proto__.__proto__,也就是Person.prototype中去找,于是就找到了alert(“Person say”)的方法。

其余的也都是同样的道理。

 函数对象创建过程

无论是在js中自定义函数,还是调用Function创建函数,最终的调用形式都是:var newFun = Function(funcArgs,funcBody);

函数对象的主要创建步骤如下:

1,创建built-in object 对象 fn;

2,将fn的[[prototype]]设置为Function.prototype;

3,设置内部的[[call]]属性;

4,设置内部的[[construct]]属性;

5,设置fn.length为funcArgs.length,如果没有参数,设置为0;

6,使用new Object 同样的逻辑创建一个Object对象fnProto

7,将fnProto.constructor设为fn

8,将fn.prototype设为fnProto

9,返回fn

js对象模型

最后来解析下面几段代码:

1,

var name = 'king_z';
function echo() {  
     alert(name);
     var name = 'pfzeng'; 
     alert(name);
     alert(age);
} 
echo();

结果是:

undefined
pfzeng
[脚本出错]

2,

function Foo() {};
var foo = new Foo();
Foo.prototype.label = "laruence";
alert(foo.label); //output: laruence
alert(Foo.label);//output: undefined

参考网站:

[1] http://www.laruence.com/jscss/page/2

[2] http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object-Model-Execution-Model.html

[3] http://www.cnblogs.com/zzcflying/archive/2012/07/20/2601112.html

原文地址:https://www.cnblogs.com/pfzeng/p/3225776.html