javascript语言精粹。3、对象;4、函数;深入原型链,对象的原理!

javascript的简单类型包括数字、字符、布尔值、null值和undefined值。

                  其他的类型都是对象。

对象是可变的键控集合。在javascript中,数组是对象,函数是对象,正则表达式是对象,对象自然也是对象。

对象是属性的容器,其中每个属性都拥有名字和值。

属性的名字可以是包括空字符串的任何字符串。属性的值可以是除了undefined之外的任意值

javascript的对象是无类别。它对新属性的名字和值没有约束。对象适合用于收集和管理数据。对象可以包含其他对象,

所以它们可以容易地表示成树形或者图形结构

javascript包括一个原型链特性,允许对象继承另一对象的属性。

 

对象字面量

对象字面量提供了一种非常方便地创建新对象值的表示法。

var empty_object={};

原型

      每个对象都连接到一个原型对象,并且它可以从中继承属性。

      所有通过对象字面量创建的对象都连接到Object.prototype这个javascript种标准的对象。

枚举

       for in 语句可用来遍历一个对象中的所有属性名。该枚举过程会列出所有的属性(包括原型中的属性)

       一般使用hasOwnProperty方法和typeof来过滤

 

函数对象

在javascript中函数就是对象。对象是“名/值”对的集合并拥有一个连到原型对象的隐藏链接.

对象字面量产生的对象链接到 Object.prototype。 函数对象连接到 Function.prototype(该

原型对象本身连接到 Object.prototype). 

每个函数在创建时有两个附加的隐藏属性: 函数的上下文和实现函数行为的代码.

每个函数对象在创建时也随带一个prototype属性。

它的值(函数对象的实例)是一个拥有constructor属性并且值即为该函数的对象。

调用

调用一个函数将暂停执行当前的函数。每个函数接收两个附加的参数:this和arguments。

this在面向对象编程中非常重要, 它的值取决于调用的模式(方法调用模式、函数调用模式、构造器调用模式、

apply调用模式)

方法调用模式 : 当一个函数保存为对象的一个属性时。我们称它为一个方法this对象即为该对象

函数调用模式 : 当一个函数并非一个对象的属性时,那么它被当做一个函数来调用

构造器调用模式:如果在一个函数前面带上new来调用,那么将创建一个隐藏链接到该函数的 prototype 成员的新对象

                          ,同时 this 将被绑定到那个新对象上

Apply调用模式

返回

一个函数总是会返回一个值。如果没有使用return指定返回,则返回undefined。

使用return语句,则return语句之后的代码不执行。

 

 

深入了解原型链、类型等

源码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title></title>
    <script type="text/javascript">
        window.onload = function() {
            var div_show = document.getElementById("div_show");
 
            Object.prototype.objprototype = function() { }
            Function.prototype.fnprototype = function() { }
            Function.fnStaticfunction = function() { }
 
 
            function people() {
                this.sex = 0;
                this.age = 1;
                this.getName = function() { }
            }
            people.eat = function() { };
            var p = new people();
            for (var i in people.prototype) {
                div_show.innerHTML += "peopleprototype:  " + i + "<br>";
            }
            div_show.innerHTML += "<br>";
            for (var i in p) {
                div_show.innerHTML += "peopleinstance:  " + i + "<br>";
            }
            div_show.innerHTML += "<br>";
            for (var i in people) {
                div_show.innerHTML += "people:  " + i + "<br>";
            }
            div_show.innerHTML += "<br>";
            
 
            function asia() { }
            asia.StaticeatEastFood = function() { }
            asia.prototype = new people();
            asia.prototype.eatEastFoodPrototype = function() { }
 
            var asian = new asia();
 
            for (var i in asian) {
                div_show.innerHTML += "asian:  " + i + "<br>";
            }
            div_show.innerHTML += "<br>";
            for (var i in asia) {
                div_show.innerHTML += "asia:  " + i + "<br>";
            }
            div_show.innerHTML += "<br>";
            for (var i in asia.prototype) {
                div_show.innerHTML += "asia:  " + i + "<br>";
            }
 
            var stooge = {
                "first-name": "J",
                "last-name": "H",
                getName: function() { }
            }
            div_show.innerHTML += "<br>";
            for (var i in stooge) {
                div_show.innerHTML += "stooge:  " + i + "<br>";
            }
 
            Function.prototype.method = function(name, value) {
                this.prototype[name] = value;
            }
            Number.method("getss", function() { });
        }
    </script>
</head>
<body>
<div id="div_show"></div>
</body>
</html>
.           Object.prototype.objprototype = function() { } 
            Function.prototype.fnprototype = function() { }
            Function.fnStaticfunction = function() { }
.           function people() {
                this.sex = 0;
                this.age = 1;
                this.getName = function() { }
            }//申明一个函数对象,  给该对象添加一个静态方法eat,  使用构造器调用函数生成实例p
            people.eat = function() { };
            var p = new people();
.           for (var i in people.prototype) {
                div_show.innerHTML += "peopleprototype:  " + i + "<br>";
            }
            div_show.innerHTML += "<br>";
            for (var i in p) {
                div_show.innerHTML += "peopleinstance:  " + i + "<br>";
            }
            div_show.innerHTML += "<br>";
            for (var i in people) {
                div_show.innerHTML += "people:  " + i + "<br>";
            }
            div_show.innerHTML += "<br>";

分析:

输出people.prototype里面的对象:

people.prototype对象为一个空的json对象,而所有的对象都会从原型链集成object.prototype的属性;
因此第一个循环输出
objprototype
 
p是函数对象people的实例,因此它拥有people.prototype的所有属性以及各个私有属性。
因此输出
objprototype
sex
age
getName
先从祖先输出。 (为什么可以输出fnprototype呢, 因为在这里使用 people instanceof Function
得到true,我这么理解的:p是people的实例,因此能够得到people.prototype内的属性;而people是
function的实例,因此只有people才能得到Function.prototype的属性)
 
直接输出people内的对象(理解为作为Function实例输出Function.prototype属性;作为people类型,
输出该“类”的静态方法)
fnprototype
objprototype
eat
 

//创建一个asia函数类, 添加一个静态方法StaticeatEastFood.
//使asia类继承自people类, 添加一个prototype方法,  实例化一个asian实例
            function asia() { }
            asia.StaticeatEastFood = function() { }
            asia.prototype = new people();
            asia.prototype.eatEastFoodPrototype = function() { }
            var asian = new asia();
.           for (var i in asian) {
                div_show.innerHTML += "asian:  " + i + "<br>";
            }
            div_show.innerHTML += "<br>";
            for (var i in asia) {
                div_show.innerHTML += "asia:  " + i + "<br>";
            }
            div_show.innerHTML += "<br>";
            for (var i in asia.prototype) {
                div_show.innerHTML += "asia:  " + i + "<br>";
            }

分析:

输出asian(asia实例)
asian: eatEastFoodPrototype //asia的prototype拥有的
asian: getName              //这三个是集成自people的
asian: age
asian: sex
asian: objprototype         //祖先object的
 
输出asia
asia: fnprototype
asia: objprototype
asia: StaticeatEastFood     //静态方法
 
输出asia.prototype
asia: objprototype      //祖先
asia: sex               //继承自people的私有属性
asia: age
asia: getName
asia: eatEastFoodPrototype //自己的公共属性
 
 
 
.           var stooge = {
                "first-name": "J",
                "last-name": "H",
                getName: function() { }
            }
            div_show.innerHTML += "<br>";
            for (var i in stooge) {
                div_show.innerHTML += "stooge:  " + i + "<br>";
            }
/*
            stooge: objprototype
            stooge: first-name
            stooge: last-name
            stooge: getName
*/
.           Function.prototype.method = function(name, value) {
                this.prototype[name] = value;
            }
/*
这是一个简单的扩展类型的方法的函数. 
比如  people.method ('run',function(){alert('人类会跑');})
这是很简单没有问题的。
可是, Function.method , Number.method , String.method , 甚至Object.method这样也能访问
这个方法为自身扩展,为什么呢?
这是因为,所有的类型其实都是Object类型的实例。Object除了prototype外还有一个很重要的属性——
constructor。这个东西就是用来完成我前面说到的对object的扩充用的,它也是我们使用JavaScript模拟
OOP的基础。由于JavaScript中所有东西都是Object,所以constructor也是,不过它的原始类型是
Function(运行Object.constructor.valueOf()得到:function Function() { [native code] })。
这么说吧。既然Number、String等既然都是类型,那么他们的实例就需要类似一个new Number()这样的过程。
那么OK,Number其实他们都是一个函数对象而已。
(Number.constructor , 得到function()).
因此,他们包括object都是function类型的,Function.prototype的属性他们都有!!!
而所有对象都是object,function也是object,和其他类型一样,
因此Function.constructor为Function,Function instanceof Object  :true
神奇吧~?!
*/
            Number.method("getss", function() { });
posted @ 2010-04-29 17:24  MyCoolDog  阅读(556)  评论(0编辑  收藏  举报