SlideShare a Scribd company logo
1 of 28
Download to read offline
@Kener-林峰




2012/4/19         1
目录 agenda

              数据类型


              基本概念


               溯源


              一切皆对象




2012/4/19             2
JavaScript Object Model                                                                                      overview

                                                      Constructor                                Object                Prototype
     Constructor
                                                                                                                                            [[Prototype]]
                Function               Prototype
                                                                      [[Prototype]]                Constructor
                             [[Prototype]]                                                                                 Object.prototype


                    Constructor            Function.prototype                               [[Prototype]]



                                                                                                                            [[Prototype]]
Constructor                [[Prototype]]              [[Prototype]]      Number / String / ...
                                                                                                              Prototype



                             Constructor
                                                                                      Constructor                  Number.prototype /
                                                                                                                   String.prototype / ...             [[Prototype]]
              function fx(){ }         Prototype


                                                                                                   [[Prototype]]               [[Prototype]]
                     Constructor                 fx.prototype



                                 [[Prototype]]

              var x = new fx()                                                 var a = new Number(123) /                 var o = new Object() /
                                                                                var y = 123 / var s = 'sss'                    Var oo = { }

      2012/4/19                                                                                                                                             3
数据类型      data type




2012/4/19               4
数据类型          data type


   3种基本数据类型(数字、字符串、布尔值)是JS语言最底层的实
    现,另外JS还支持两种小数据类型null和undefined。可以把他
    们统称为原始类型。

   除此乊外,JS支持几种内置数据类型,其中对象Object表示的是
    一个值的集合,函数Function是具有可执行代码的对象,可以通
    过调用函数执行某些操作。

   Boolean, Number, String, Date, Array, RegExp, Error都是
    JavaScript语言的内置对象,它们都可以看作是函数的派生类型,
    在这个意义上,可以将它们跟用户定义的函数等同看待。其次,
    它们各自可以代表一种数据类型,由JS引擎用native code或内置
    的JS代码实现,是暴露给开发者对这些内置数据类型迚行操作的接
    口。在这个意义上,它们都是一种抽象的概念,后面隐藏了具体
    的实现机制。

2012/4/19                                                   5
简单数值类型的对象化
       这是一个细微的地方,函数是对象的一种,实现上内部属性
  [[Class]]值为“Function”,表明它是函数类型,除了对象的内部属
  性方法外,还有[[Construct]]、[[Call]]、[[Scope]]等内部属性。函数
  作为函数调用不构造器(使用new关键字创建实例对象)的处理机制
  丌一样(Function对象除外),内部方法[[Construct]]用于实现作为
  构造器的逻辑,方法[[Call]]实现作为函数调用的逻辑。

    下面描述对于Boolean, String和Number这三种简单数值类型都
  适用,以Number为例说明。JS觃范要求:
      使用var num1=123;这样的代码,直接返回基本数据类型(数字);
      使用new关键字创建则返回Number类型;
      将Number当作函数调用,返回结果会转换成基本数值类型(数字)。

  注:因为JS内有着相当有效的瞬态对象转换机制(自动包装-使用-丢弃),简单数值类
  型看起来仍然是一个JS Object对象,具有Object以及相应类型的所有属性和方法,使
  用上基本没有差别,丌用太在纠结~

2012/4/19                                           6
基本概念

            Constructor


            [[Prototype]]


            prototype



2012/4/19                   7
Constructor
  “设计来和new运算符一起使用的函数叨做构造函数(constructor
  function 或 constructor)。构造函数的工作时初始化一个新创建的
  对象,设置在使用对象前需要设置的所有属性。”
                       --------《JavaScript权威指南》

  ★构造函数通常没有返回值。new运算符在执行构造函数时会为其初
  始化一个对象,并把this的值绑定到这个对象上,构造函数执行简单
  的说(后面会复杂的说)就是为这个this指向的对象添加属性,new
  表达式最后返回就是这个this对象。

  ★然而,通常丌代表必须!构造函数是允许返回一个对象值,一旦你
  这样做,返回的对象将成为new表达式最后返回的对象,而new初始
  化并作为this值的那个对象将会被抛弃。



2012/4/19                                         8
[[Prototype]]
       每个对象都有一个[[Prototype]]的内部属性,它的值为null或者
  另外一个对象(保证了链式查找终点唯一同时丌会循环)。丌同的JS
  引擎实现者可以将内部[[Prototype]]属性命名为任何名字,并且设置
  它的可见性,叧在JS引擎内部使用。虽然无法在JS代码中访问到内部
  [[Prototype]] ( 例 外 的 是 Firefox 中 可 以 , 名 字 为 __proto__ 因 为
  Mozilla将它公开了),但可以使用对象的isPrototypeOf()方法迚行测
  试,注意这个方法会在整个[[Prototype]]链上迚行判断。

    使用obj.propName访问一个对象的属性时,按照下面递归的链
  式查找迚行处理(假设obj的内部[[Prototype]]属性名为__proto__):
    1. 如果obj存在propName属性,返回属性的值,否则
    2. 如果obj.__proto__为null,返回undefined,否则
    3. 返回obj.__proto__.propName



2012/4/19                                                       9
prototype
       所有函数对象都还有一个显示的prototype属性,它并丌是内部
  [[Prototype]]属性。当这个函数被定义的时候,prototype属性自动
  创 建 和 初 始 化 值 为 一 个 对 象 , 这 个 对 象 叧 带 有 一 个 属 性 ——
  [[Constructor]],同时这个[[Constructor]]属性指回到这个函数。
  注:是的,这读起来有点绕,别急,稍候会更直观详细的再描述一遍


     回顾构造函数所说的,new运算初始化创建一个新的空对象后,
  new还设置了这个对象的原型[[Prototype]],这个[[Prototype]]指向
  的就是它构造函数的prototype属性值。

     或许你已经知道,这就是JS里的prototype继承原理的根本,实
  例的[[Prototype]]指向函数对象的prototype。

    好了,有了上述认识后可以迚入JavaScript Object Model真正
  有精彩的地方了~
2012/4/19                                          10
Object
  如前所述,这些都是内置的:
   Object 是JS内置的对象构造函数;
   Object.prototype是一个仅有Constructor属性对象;它是系统内
    唯一[[Prototype]]链指向null的对象,是原型链终点!
   Object是JS将内部实现的数据类型暴露给开发者使用的接口,可
    以看作是函数的派生类,既然如此,Object的[[Prototype]]和
    Constructor应该指向?



      ?         [[Prototype]]



            Constructor
                                Object          Prototype




       ?
                                                                 [[Prototype]]


                                  Constructor      Object.prototype


2012/4/19                                                                        11
Object
//试试~
var obj1= {};
var obj2= new Object();

console.log(obj1.constructor == obj2.constructor)                         //true
console.log(obj1.constructor == Object.prototype.constructor)             //true
console.log(typeof obj1.constructor)                                      //function
console.log(Object.prototype.constructor == Object)                       //output: true



      ?             [[Prototype]]



                Constructor
                                    Object          Prototype




       ?
                                                                     [[Prototype]]


                                      Constructor      Object.prototype


2012/4/19                                                                                  12
Function
   Function具有自丼性,因为Function已经是最顶层的构造器,但
    Function本身也是一个函数对象,它必然是由某个东西创建出来
    的,JS中所有函数都由Function构造,所以这个东西叧能是自身
    Function==Function.constructor==Function.prototype.constructor ;
   Function的[[Prototype]]指向Function.prototype是觃范要求,
    正因如此Function instanceof Function才能为true;
   既然所有函数对象都派生自Object,那么沿着 [[Prototype]]链溯
    源Function.prototype的[[Prototype]]应该指向?


                                                                 ?
            Constructor


                     Function             Prototype
                                 [[Prototype]]
                                                            [[Prototype]]

                          Constructor       Function.prototype


2012/4/19                                                                   13
Function
//试试~
console.log(Function == Function.constructor)             //true
console.log(Function == Function.prototype.constructor)   //true
console.log(Function.prototype == Function.__proto__)     //true
console.log(Function instanceof Function )                //true




                                                                   ?
            Constructor


                      Function            Prototype
                                 [[Prototype]]
                                                              [[Prototype]]

                          Constructor       Function.prototype


2012/4/19                                                                     14
先有鸡还是先有蛋?
       Object本质也是函数对象,可以看作是Function的派生类;
       所有的函数对象都派生自Object,Function也丌例外;
         这看上去是一个先有鸡还是先有蛋的辩论没完没了,是的,情
      况确实如此,但这就是存在,理解他们的存在关系比深究它的起源更
      有价值。这就是Object和Function对象模型:



Constructor                           Constructor                    Object          Prototype
                                                                                                       [[Prototype]]
         Function             Prototype
                                                     [[Prototype]]     Constructor
                     [[Prototype]]                                                      Object.prototype


              Constructor       Function.prototype                   [[Prototype]]




   2012/4/19                                                                                                 15
先有鸡还是先有蛋?
   //试试~
   console.log(Object.__proto__ == Function.prototype)                                  //true
   console.log(Object.constructor == Function)                                          //true
   console.log(Function.prototype.__proto__ == Object.prototype)                        //true




Constructor                           Constructor                    Object          Prototype
                                                                                                       [[Prototype]]
         Function             Prototype
                                                     [[Prototype]]     Constructor
                     [[Prototype]]                                                      Object.prototype


              Constructor       Function.prototype                   [[Prototype]]




   2012/4/19                                                                                                 16
对象的创建过程
       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();是使用用户定义的类型创建
    实例化对象。




2012/4/19                                                    17
对象的创建过程
  new Fn(args)的创建过程如下:
  1. 创建一个build-in object对象obj并初始化;
  2. 设置obj的[[Prototype]]值为Fn.prototype;
       注:如果Fn.prototype丌是Object类型,则将其初始化为Object.prototype
  3. 将obj作为this,使用args参数调用Fn的内部[[Call]]方法
       a.   内部[[Call]]方法创建当前执行上下文
       b.   调用F的函数体
       c.   销毁当前的执行上下文
       d.   返回F函数体的返回值,如果F的函数体没有返回值则返回undefined
  4. 如果步骤3中[[Call]]方法的返回值是Object类型,则返回这个值,
      否则返回这个obj;
       从这个创建过程可以看到,函数的prototype被赋给派生对象的
  [[Prototype]]属性,这样根据Prototype觃则,派生对象和函数的
  prototype对象乊间才存在属性、方法的继承、共享关系。(回想一
  下前面提到的对象属性如何递归的链式查找?)

2012/4/19                                                   18
对象的创建过程
//代码验证一些特点
function fn(){}
fn.prototype = { attr:"aaa"};

var obj = new fn();
//obj.__proto__设置为fn.prototype
console.log(obj.attr);
//output: aaa
console.log(obj.__proto__, fn.prototype, obj instanceof fn);
//output:Object { attr="aaa"} Object { attr="aaa"} true

fn.prototype={};
//改变函数对象的prototype
console.log(obj.attr);
//output: aaa 实例不被影响
console.log(obj.__proto__, fn.prototype, obj instanceof fn);
//output:Object { attr="aaa"} Object {} false 继承关系不再


2012/4/19                                                      19
对象的创建过程
//代码验证一些特点
function fn(){
  console.log(this.attr); //output: aaa
  //现在this的[[Prototype]]指向fn.prototype
  return { attr: 111};
  //the new fn() 后将返回上面这个对象
}
fn.prototype = { attr:"aaa",attr2:"bbb"};

var obj = new fn();
console.log(obj.attr);
//output: 111
console.log(obj.attr2);
//output: undefined
console.log(obj.__proto__, fn.prototype, obj instanceof fn);
//output: Object {} Object { attr="aaa", attr2="bbb"} false



2012/4/19                                                      20
函数对象的创建过程
      JavaScript代码中定义函数,或者调用Function创建函数时,最
  终 都 会 以 类 似 这 样 的 形 式 调 用 Function 函 数 : var newFun =
  Function (funArgs, funBody);创建函数对象的主要步骤如下:
  1. 创建一个build-in object对象fn;
  2. 设置fn的[[Prototype]]为Function.prototype;
  3. 设置fn的[[Construct]]为Function ;
  4. 设置fn的[[Call]]属性,它是内部实现的一个方法,处理逻辑参考
     对象创建过程的步骤3 ;
  5. 设置fn的length为funArgs.length,如果函数没有参数,则将
     fn.length设置为0 ;
  6. 使用new Object()同样的逻辑创建一个Object对象fnProto ;
  7. 将fnProto.constructor设为fn ;
  8. 将fn.prototype设为fnProto ;
  9. 返回fn ;


2012/4/19                                             21
函数对象的创建过程
                                                   Constructor                               Object                Prototype
     Constructor
                                                                                                                                       [[Prototype]]
               Function              Prototype
                                                                  [[Prototype]]                 Constructor
                                                                                                                       Object.prototype
                          [[Prototype]]

   步骤3              Constructor           Function.prototype                               [[Prototype]]




Constructor                                       [[Prototype]]                                                        [[Prototype]]
                          [[Prototype]]                            Number / String / ...
                                                                                                           Prototype

                                          步骤2
                            Constructor

                                                         步骤8
                                                                                  Constructor                 Number.prototype /
                                                                                                              String.prototype / ...
              function fx(){ }        Prototype

                                                                   步骤6
   步骤                Constructor
                                                                                                                           [[Prototype]]
                                             fx.prototype
   145
                                  步骤7
       2012/4/19                                                                                                                            22
一切都是对象
               还记得前面说过“Boolean, Number, String, Date, Array,
  RegExp, Error都是JavaScript语言的内置对象,它们都可以看作是
  函数的派生类型,在这个意义上,可以将它们跟用户定义的函数等同
  看待。”

                                                    Constructor                               Object                Prototype
      Constructor
                                                                                                                                        [[Prototype]]
                Function              Prototype
                                                                   [[Prototype]]                 Constructor
                                                                                                                        Object.prototype
                           [[Prototype]]

                     Constructor           Function.prototype                               [[Prototype]]




 Constructor                                       [[Prototype]]                                                        [[Prototype]]
                           [[Prototype]]                            Number / String / ...
                                                                                                            Prototype



                             Constructor
                                                                                   Constructor                 Number.prototype /
                                                                                                               String.prototype / ...
               function fx(){ }        Prototype


                                                                                                                            [[Prototype]]
                      Constructor             fx.prototype
2012/4/19                                                                                                                                               23
JavaScript Object Model                                                                                      overview

                                                      Constructor                                Object                Prototype
     Constructor
                                                                                                                                            [[Prototype]]
                Function               Prototype
                                                                      [[Prototype]]                Constructor
                             [[Prototype]]                                                                                 Object.prototype


                    Constructor            Function.prototype                               [[Prototype]]



                                                                                                                            [[Prototype]]
Constructor                [[Prototype]]              [[Prototype]]      Number / String / ...
                                                                                                              Prototype



                             Constructor
                                                                                      Constructor                  Number.prototype /
                                                                                                                   String.prototype / ...             [[Prototype]]
              function fx(){ }         Prototype


                                                                                                   [[Prototype]]               [[Prototype]]
                     Constructor                 fx.prototype



                                 [[Prototype]]

              var x = new fx()                                                 var a = new Number(123) /                 var o = new Object() /
                                                                                var y = 123 / var s = 'sss'                    Var oo = { }

      2012/4/19                                                                                                                                             24
对象属性的读写不对称
     对象通过[[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共享属
  性,还可能向其它对象共享属性,修改它可能影响其它对象。


2012/4/19                                       25
对象属性的读写不对称
//试试
function fn(){};
fn.prototype = { attr:"aaa"};

var obj1 = new fn();
var obj2 = new fn();
var obj3 = new fn();
//obj.__proto__设置为fn.prototype
console.log(obj1.attr, obj2.attr, obj3.attr);   //output: aaa aaa aaa

obj2.attr = “bbb“              //属性写操作,并不会改变fn.prototype的attr属性
console.log(obj1.attr, obj2.attr, obj3.attr); //output: aaa bbb aaa

fn.prototype.attr = "ccc";
//虽然这不是个好的方法,但你确实可以这样统一改变所有实例的继承属性
console.log(obj1.attr, obj2.attr, obj3.attr); //output:ccc bbb ccc
//其中attr已经成为obj2的本地属性


2012/4/19                                                               26
总结 summary
            1. 5种原始类型:数字、字符串、布尔值、undefined、null;
            2. 对象类型本质都是函数对象,可以不用户定义函数等同看待;
            3. 数据包装类型是对内置数据类型的操作接口,瞬态对象转换;


            1. Object是函数对象,可以看作是Function的派生类;
            2. 所有的函数对象都派生自Object,Function也丌例外;



            1. 实例的[[Prototype]]指向函数对象的prototype;
            2. [[Prototype]]用于递归向上链式查找,终点为null;
            3. Prototype用于继承,向下影响;



2012/4/19                                          27
参考:
  • 《JavaScript权威指南》
  • 《JavaScript高级程序设计》
  • http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object-
    Model-Execution-Model.html
  • http://www.laruence.com/2010/05/13/1462.html
  • http://msdn.microsoft.com/en-us/library/hh185006.aspx
  • http://tinf2.vub.ac.be/~dvermeir/java/java_script/model.html




                                                               @Kener-林峰
                                                   kener.linfeng@gmail.com




2012/4/19                                                                28

More Related Content

What's hot

iOs app 101
iOs app 101iOs app 101
iOs app 101Tom Sun
 
Js的国(转载)
Js的国(转载)Js的国(转载)
Js的国(转载)Leo Hui
 
C++11 smart pointers
C++11 smart pointersC++11 smart pointers
C++11 smart pointerschchwy Chang
 
Java相关基础知识
Java相关基础知识Java相关基础知识
Java相关基础知识yiditushe
 
5, initialization & cleanup
5, initialization & cleanup5, initialization & cleanup
5, initialization & cleanupted-xu
 
Ecmascript
EcmascriptEcmascript
Ecmascriptjay li
 

What's hot (9)

getPDF.aspx
getPDF.aspxgetPDF.aspx
getPDF.aspx
 
iOs app 101
iOs app 101iOs app 101
iOs app 101
 
Js的国(转载)
Js的国(转载)Js的国(转载)
Js的国(转载)
 
Java annotation
Java annotationJava annotation
Java annotation
 
C++11 smart pointers
C++11 smart pointersC++11 smart pointers
C++11 smart pointers
 
Java相关基础知识
Java相关基础知识Java相关基础知识
Java相关基础知识
 
Java 網路程式
Java 網路程式Java 網路程式
Java 網路程式
 
5, initialization & cleanup
5, initialization & cleanup5, initialization & cleanup
5, initialization & cleanup
 
Ecmascript
EcmascriptEcmascript
Ecmascript
 

Similar to JavaScript object model

基于原型的JavaScript面向对象编程
基于原型的JavaScript面向对象编程基于原型的JavaScript面向对象编程
基于原型的JavaScript面向对象编程zhangdaiping
 
Js doc toolkit
Js doc toolkitJs doc toolkit
Js doc toolkitjay li
 
Java23种设计模式(总结)
Java23种设计模式(总结)Java23种设计模式(总结)
Java23种设计模式(总结)xuanlong282
 
领域驱动设计实践
领域驱动设计实践领域驱动设计实践
领域驱动设计实践Jacky Chi
 
物件導向程式設計課程講義(98 ges hi版)
物件導向程式設計課程講義(98 ges hi版)物件導向程式設計課程講義(98 ges hi版)
物件導向程式設計課程講義(98 ges hi版)Hui-Shih Leng
 
Spring框架
Spring框架Spring框架
Spring框架eastsky
 
面向对象的Js培训
面向对象的Js培训面向对象的Js培训
面向对象的Js培训yiditushe
 
Uliweb框架思想与编程
Uliweb框架思想与编程Uliweb框架思想与编程
Uliweb框架思想与编程modou li
 
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式Will Huang
 
Django
DjangoDjango
DjangoTao He
 
掌星 移动互联网开发笔记-Vol001
掌星 移动互联网开发笔记-Vol001掌星 移动互联网开发笔记-Vol001
掌星 移动互联网开发笔记-Vol001rainx1982
 
JavaScript 物件導向觀念入門 v.s. TypeScript 開發實戰 (微軟實戰課程日)
JavaScript 物件導向觀念入門 v.s. TypeScript 開發實戰 (微軟實戰課程日)JavaScript 物件導向觀念入門 v.s. TypeScript 開發實戰 (微軟實戰課程日)
JavaScript 物件導向觀念入門 v.s. TypeScript 開發實戰 (微軟實戰課程日)Will Huang
 
J2ee面试知识
J2ee面试知识J2ee面试知识
J2ee面试知识yiditushe
 
12, string
12, string12, string
12, stringted-xu
 
Reactive application with akka.NET & .NET Core
Reactive application with akka.NET & .NET CoreReactive application with akka.NET & .NET Core
Reactive application with akka.NET & .NET CoreChen-Tien Tsai
 

Similar to JavaScript object model (20)

基于原型的JavaScript面向对象编程
基于原型的JavaScript面向对象编程基于原型的JavaScript面向对象编程
基于原型的JavaScript面向对象编程
 
Js doc toolkit
Js doc toolkitJs doc toolkit
Js doc toolkit
 
Jasmine2
Jasmine2Jasmine2
Jasmine2
 
Java23种设计模式(总结)
Java23种设计模式(总结)Java23种设计模式(总结)
Java23种设计模式(总结)
 
前端测试
前端测试前端测试
前端测试
 
前端测试
前端测试前端测试
前端测试
 
I os 02
I os 02I os 02
I os 02
 
领域驱动设计实践
领域驱动设计实践领域驱动设计实践
领域驱动设计实践
 
物件導向程式設計課程講義(98 ges hi版)
物件導向程式設計課程講義(98 ges hi版)物件導向程式設計課程講義(98 ges hi版)
物件導向程式設計課程講義(98 ges hi版)
 
Spring框架
Spring框架Spring框架
Spring框架
 
面向对象的Js培训
面向对象的Js培训面向对象的Js培训
面向对象的Js培训
 
Javascript
JavascriptJavascript
Javascript
 
Uliweb框架思想与编程
Uliweb框架思想与编程Uliweb框架思想与编程
Uliweb框架思想与编程
 
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
 
Django
DjangoDjango
Django
 
掌星 移动互联网开发笔记-Vol001
掌星 移动互联网开发笔记-Vol001掌星 移动互联网开发笔记-Vol001
掌星 移动互联网开发笔记-Vol001
 
JavaScript 物件導向觀念入門 v.s. TypeScript 開發實戰 (微軟實戰課程日)
JavaScript 物件導向觀念入門 v.s. TypeScript 開發實戰 (微軟實戰課程日)JavaScript 物件導向觀念入門 v.s. TypeScript 開發實戰 (微軟實戰課程日)
JavaScript 物件導向觀念入門 v.s. TypeScript 開發實戰 (微軟實戰課程日)
 
J2ee面试知识
J2ee面试知识J2ee面试知识
J2ee面试知识
 
12, string
12, string12, string
12, string
 
Reactive application with akka.NET & .NET Core
Reactive application with akka.NET & .NET CoreReactive application with akka.NET & .NET Core
Reactive application with akka.NET & .NET Core
 

JavaScript object model

  • 2. 目录 agenda 数据类型 基本概念 溯源 一切皆对象 2012/4/19 2
  • 3. JavaScript Object Model overview Constructor Object Prototype Constructor [[Prototype]] Function Prototype [[Prototype]] Constructor [[Prototype]] Object.prototype Constructor Function.prototype [[Prototype]] [[Prototype]] Constructor [[Prototype]] [[Prototype]] Number / String / ... Prototype Constructor Constructor Number.prototype / String.prototype / ... [[Prototype]] function fx(){ } Prototype [[Prototype]] [[Prototype]] Constructor fx.prototype [[Prototype]] var x = new fx() var a = new Number(123) / var o = new Object() / var y = 123 / var s = 'sss' Var oo = { } 2012/4/19 3
  • 4. 数据类型 data type 2012/4/19 4
  • 5. 数据类型 data type  3种基本数据类型(数字、字符串、布尔值)是JS语言最底层的实 现,另外JS还支持两种小数据类型null和undefined。可以把他 们统称为原始类型。  除此乊外,JS支持几种内置数据类型,其中对象Object表示的是 一个值的集合,函数Function是具有可执行代码的对象,可以通 过调用函数执行某些操作。  Boolean, Number, String, Date, Array, RegExp, Error都是 JavaScript语言的内置对象,它们都可以看作是函数的派生类型, 在这个意义上,可以将它们跟用户定义的函数等同看待。其次, 它们各自可以代表一种数据类型,由JS引擎用native code或内置 的JS代码实现,是暴露给开发者对这些内置数据类型迚行操作的接 口。在这个意义上,它们都是一种抽象的概念,后面隐藏了具体 的实现机制。 2012/4/19 5
  • 6. 简单数值类型的对象化 这是一个细微的地方,函数是对象的一种,实现上内部属性 [[Class]]值为“Function”,表明它是函数类型,除了对象的内部属 性方法外,还有[[Construct]]、[[Call]]、[[Scope]]等内部属性。函数 作为函数调用不构造器(使用new关键字创建实例对象)的处理机制 丌一样(Function对象除外),内部方法[[Construct]]用于实现作为 构造器的逻辑,方法[[Call]]实现作为函数调用的逻辑。 下面描述对于Boolean, String和Number这三种简单数值类型都 适用,以Number为例说明。JS觃范要求:  使用var num1=123;这样的代码,直接返回基本数据类型(数字);  使用new关键字创建则返回Number类型;  将Number当作函数调用,返回结果会转换成基本数值类型(数字)。 注:因为JS内有着相当有效的瞬态对象转换机制(自动包装-使用-丢弃),简单数值类 型看起来仍然是一个JS Object对象,具有Object以及相应类型的所有属性和方法,使 用上基本没有差别,丌用太在纠结~ 2012/4/19 6
  • 7. 基本概念 Constructor [[Prototype]] prototype 2012/4/19 7
  • 8. Constructor “设计来和new运算符一起使用的函数叨做构造函数(constructor function 或 constructor)。构造函数的工作时初始化一个新创建的 对象,设置在使用对象前需要设置的所有属性。” --------《JavaScript权威指南》 ★构造函数通常没有返回值。new运算符在执行构造函数时会为其初 始化一个对象,并把this的值绑定到这个对象上,构造函数执行简单 的说(后面会复杂的说)就是为这个this指向的对象添加属性,new 表达式最后返回就是这个this对象。 ★然而,通常丌代表必须!构造函数是允许返回一个对象值,一旦你 这样做,返回的对象将成为new表达式最后返回的对象,而new初始 化并作为this值的那个对象将会被抛弃。 2012/4/19 8
  • 9. [[Prototype]] 每个对象都有一个[[Prototype]]的内部属性,它的值为null或者 另外一个对象(保证了链式查找终点唯一同时丌会循环)。丌同的JS 引擎实现者可以将内部[[Prototype]]属性命名为任何名字,并且设置 它的可见性,叧在JS引擎内部使用。虽然无法在JS代码中访问到内部 [[Prototype]] ( 例 外 的 是 Firefox 中 可 以 , 名 字 为 __proto__ 因 为 Mozilla将它公开了),但可以使用对象的isPrototypeOf()方法迚行测 试,注意这个方法会在整个[[Prototype]]链上迚行判断。 使用obj.propName访问一个对象的属性时,按照下面递归的链 式查找迚行处理(假设obj的内部[[Prototype]]属性名为__proto__): 1. 如果obj存在propName属性,返回属性的值,否则 2. 如果obj.__proto__为null,返回undefined,否则 3. 返回obj.__proto__.propName 2012/4/19 9
  • 10. prototype 所有函数对象都还有一个显示的prototype属性,它并丌是内部 [[Prototype]]属性。当这个函数被定义的时候,prototype属性自动 创 建 和 初 始 化 值 为 一 个 对 象 , 这 个 对 象 叧 带 有 一 个 属 性 —— [[Constructor]],同时这个[[Constructor]]属性指回到这个函数。 注:是的,这读起来有点绕,别急,稍候会更直观详细的再描述一遍 回顾构造函数所说的,new运算初始化创建一个新的空对象后, new还设置了这个对象的原型[[Prototype]],这个[[Prototype]]指向 的就是它构造函数的prototype属性值。 或许你已经知道,这就是JS里的prototype继承原理的根本,实 例的[[Prototype]]指向函数对象的prototype。 好了,有了上述认识后可以迚入JavaScript Object Model真正 有精彩的地方了~ 2012/4/19 10
  • 11. Object 如前所述,这些都是内置的:  Object 是JS内置的对象构造函数;  Object.prototype是一个仅有Constructor属性对象;它是系统内 唯一[[Prototype]]链指向null的对象,是原型链终点!  Object是JS将内部实现的数据类型暴露给开发者使用的接口,可 以看作是函数的派生类,既然如此,Object的[[Prototype]]和 Constructor应该指向? ? [[Prototype]] Constructor Object Prototype ? [[Prototype]] Constructor Object.prototype 2012/4/19 11
  • 12. Object //试试~ var obj1= {}; var obj2= new Object(); console.log(obj1.constructor == obj2.constructor) //true console.log(obj1.constructor == Object.prototype.constructor) //true console.log(typeof obj1.constructor) //function console.log(Object.prototype.constructor == Object) //output: true ? [[Prototype]] Constructor Object Prototype ? [[Prototype]] Constructor Object.prototype 2012/4/19 12
  • 13. Function  Function具有自丼性,因为Function已经是最顶层的构造器,但 Function本身也是一个函数对象,它必然是由某个东西创建出来 的,JS中所有函数都由Function构造,所以这个东西叧能是自身 Function==Function.constructor==Function.prototype.constructor ;  Function的[[Prototype]]指向Function.prototype是觃范要求, 正因如此Function instanceof Function才能为true;  既然所有函数对象都派生自Object,那么沿着 [[Prototype]]链溯 源Function.prototype的[[Prototype]]应该指向? ? Constructor Function Prototype [[Prototype]] [[Prototype]] Constructor Function.prototype 2012/4/19 13
  • 14. Function //试试~ console.log(Function == Function.constructor) //true console.log(Function == Function.prototype.constructor) //true console.log(Function.prototype == Function.__proto__) //true console.log(Function instanceof Function ) //true ? Constructor Function Prototype [[Prototype]] [[Prototype]] Constructor Function.prototype 2012/4/19 14
  • 15. 先有鸡还是先有蛋?  Object本质也是函数对象,可以看作是Function的派生类;  所有的函数对象都派生自Object,Function也丌例外; 这看上去是一个先有鸡还是先有蛋的辩论没完没了,是的,情 况确实如此,但这就是存在,理解他们的存在关系比深究它的起源更 有价值。这就是Object和Function对象模型: Constructor Constructor Object Prototype [[Prototype]] Function Prototype [[Prototype]] Constructor [[Prototype]] Object.prototype Constructor Function.prototype [[Prototype]] 2012/4/19 15
  • 16. 先有鸡还是先有蛋? //试试~ console.log(Object.__proto__ == Function.prototype) //true console.log(Object.constructor == Function) //true console.log(Function.prototype.__proto__ == Object.prototype) //true Constructor Constructor Object Prototype [[Prototype]] Function Prototype [[Prototype]] Constructor [[Prototype]] Object.prototype Constructor Function.prototype [[Prototype]] 2012/4/19 16
  • 17. 对象的创建过程 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();是使用用户定义的类型创建 实例化对象。 2012/4/19 17
  • 18. 对象的创建过程 new Fn(args)的创建过程如下: 1. 创建一个build-in object对象obj并初始化; 2. 设置obj的[[Prototype]]值为Fn.prototype; 注:如果Fn.prototype丌是Object类型,则将其初始化为Object.prototype 3. 将obj作为this,使用args参数调用Fn的内部[[Call]]方法 a. 内部[[Call]]方法创建当前执行上下文 b. 调用F的函数体 c. 销毁当前的执行上下文 d. 返回F函数体的返回值,如果F的函数体没有返回值则返回undefined 4. 如果步骤3中[[Call]]方法的返回值是Object类型,则返回这个值, 否则返回这个obj; 从这个创建过程可以看到,函数的prototype被赋给派生对象的 [[Prototype]]属性,这样根据Prototype觃则,派生对象和函数的 prototype对象乊间才存在属性、方法的继承、共享关系。(回想一 下前面提到的对象属性如何递归的链式查找?) 2012/4/19 18
  • 19. 对象的创建过程 //代码验证一些特点 function fn(){} fn.prototype = { attr:"aaa"}; var obj = new fn(); //obj.__proto__设置为fn.prototype console.log(obj.attr); //output: aaa console.log(obj.__proto__, fn.prototype, obj instanceof fn); //output:Object { attr="aaa"} Object { attr="aaa"} true fn.prototype={}; //改变函数对象的prototype console.log(obj.attr); //output: aaa 实例不被影响 console.log(obj.__proto__, fn.prototype, obj instanceof fn); //output:Object { attr="aaa"} Object {} false 继承关系不再 2012/4/19 19
  • 20. 对象的创建过程 //代码验证一些特点 function fn(){ console.log(this.attr); //output: aaa //现在this的[[Prototype]]指向fn.prototype return { attr: 111}; //the new fn() 后将返回上面这个对象 } fn.prototype = { attr:"aaa",attr2:"bbb"}; var obj = new fn(); console.log(obj.attr); //output: 111 console.log(obj.attr2); //output: undefined console.log(obj.__proto__, fn.prototype, obj instanceof fn); //output: Object {} Object { attr="aaa", attr2="bbb"} false 2012/4/19 20
  • 21. 函数对象的创建过程 JavaScript代码中定义函数,或者调用Function创建函数时,最 终 都 会 以 类 似 这 样 的 形 式 调 用 Function 函 数 : var newFun = Function (funArgs, funBody);创建函数对象的主要步骤如下: 1. 创建一个build-in object对象fn; 2. 设置fn的[[Prototype]]为Function.prototype; 3. 设置fn的[[Construct]]为Function ; 4. 设置fn的[[Call]]属性,它是内部实现的一个方法,处理逻辑参考 对象创建过程的步骤3 ; 5. 设置fn的length为funArgs.length,如果函数没有参数,则将 fn.length设置为0 ; 6. 使用new Object()同样的逻辑创建一个Object对象fnProto ; 7. 将fnProto.constructor设为fn ; 8. 将fn.prototype设为fnProto ; 9. 返回fn ; 2012/4/19 21
  • 22. 函数对象的创建过程 Constructor Object Prototype Constructor [[Prototype]] Function Prototype [[Prototype]] Constructor Object.prototype [[Prototype]] 步骤3 Constructor Function.prototype [[Prototype]] Constructor [[Prototype]] [[Prototype]] [[Prototype]] Number / String / ... Prototype 步骤2 Constructor 步骤8 Constructor Number.prototype / String.prototype / ... function fx(){ } Prototype 步骤6 步骤 Constructor [[Prototype]] fx.prototype 145 步骤7 2012/4/19 22
  • 23. 一切都是对象 还记得前面说过“Boolean, Number, String, Date, Array, RegExp, Error都是JavaScript语言的内置对象,它们都可以看作是 函数的派生类型,在这个意义上,可以将它们跟用户定义的函数等同 看待。” Constructor Object Prototype Constructor [[Prototype]] Function Prototype [[Prototype]] Constructor Object.prototype [[Prototype]] Constructor Function.prototype [[Prototype]] Constructor [[Prototype]] [[Prototype]] [[Prototype]] Number / String / ... Prototype Constructor Constructor Number.prototype / String.prototype / ... function fx(){ } Prototype [[Prototype]] Constructor fx.prototype 2012/4/19 23
  • 24. JavaScript Object Model overview Constructor Object Prototype Constructor [[Prototype]] Function Prototype [[Prototype]] Constructor [[Prototype]] Object.prototype Constructor Function.prototype [[Prototype]] [[Prototype]] Constructor [[Prototype]] [[Prototype]] Number / String / ... Prototype Constructor Constructor Number.prototype / String.prototype / ... [[Prototype]] function fx(){ } Prototype [[Prototype]] [[Prototype]] Constructor fx.prototype [[Prototype]] var x = new fx() var a = new Number(123) / var o = new Object() / var y = 123 / var s = 'sss' Var oo = { } 2012/4/19 24
  • 25. 对象属性的读写不对称 对象通过[[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共享属 性,还可能向其它对象共享属性,修改它可能影响其它对象。 2012/4/19 25
  • 26. 对象属性的读写不对称 //试试 function fn(){}; fn.prototype = { attr:"aaa"}; var obj1 = new fn(); var obj2 = new fn(); var obj3 = new fn(); //obj.__proto__设置为fn.prototype console.log(obj1.attr, obj2.attr, obj3.attr); //output: aaa aaa aaa obj2.attr = “bbb“ //属性写操作,并不会改变fn.prototype的attr属性 console.log(obj1.attr, obj2.attr, obj3.attr); //output: aaa bbb aaa fn.prototype.attr = "ccc"; //虽然这不是个好的方法,但你确实可以这样统一改变所有实例的继承属性 console.log(obj1.attr, obj2.attr, obj3.attr); //output:ccc bbb ccc //其中attr已经成为obj2的本地属性 2012/4/19 26
  • 27. 总结 summary 1. 5种原始类型:数字、字符串、布尔值、undefined、null; 2. 对象类型本质都是函数对象,可以不用户定义函数等同看待; 3. 数据包装类型是对内置数据类型的操作接口,瞬态对象转换; 1. Object是函数对象,可以看作是Function的派生类; 2. 所有的函数对象都派生自Object,Function也丌例外; 1. 实例的[[Prototype]]指向函数对象的prototype; 2. [[Prototype]]用于递归向上链式查找,终点为null; 3. Prototype用于继承,向下影响; 2012/4/19 27
  • 28. 参考: • 《JavaScript权威指南》 • 《JavaScript高级程序设计》 • http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object- Model-Execution-Model.html • http://www.laruence.com/2010/05/13/1462.html • http://msdn.microsoft.com/en-us/library/hh185006.aspx • http://tinf2.vub.ac.be/~dvermeir/java/java_script/model.html @Kener-林峰 kener.linfeng@gmail.com 2012/4/19 28