zoukankan      html  css  js  c++  java
  • 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() { });
  • 相关阅读:
    Java集合:HashMap底层实现和原理(源码解析)
    Java获取异常堆栈信息
    win7 64位系统 PB连接oracle数据库出现“oracle library oci.dll could not be loaded”问题的解决方法
    Oralce 使用递归方式获取BOM树显示结构
    Oracle 链接数据库语句
    根据数据窗口某列的值定位行
    pb中数据窗口filter函数和retrieve函数的区别和联系
    用代码保存共享文件夹登录名和密码
    PB 组合数据窗口子窗口数据赋值方法
    PB 导出PDF
  • 原文地址:https://www.cnblogs.com/jianjialin/p/1724165.html
Copyright © 2011-2022 走看看