• 关于JavaScript继承和prototype的一点体会(一)


    JavaScript中的prototype很容易使初学者迷惑不解,我也刚开始学习这门语言,写了一小段代码帮助理解。(千言万语,尽在注释中:)

      1、首先是一个简单的函数来判断是否是JavaScript中的对象。JavaScript中的数据类型分为原始类型和对象类型(包括函数)

     1 function isObject(object) {
     2 
     3     //注意,undefined == null,过滤掉null和undefined
     4     if(object == null) throw TypeError();
     5 
     6     //object的类型,过滤掉原始类型如数字,字符串和布尔值
     7     var type = typeof object;
     8 
     9     if(type !== "object" && type !== "function") throw TypeError();
    10 
    11     //object是一个对象
    12     return true;
    13 }

      2、实现一个继承方法,返回一个子对象。

     1 function inherit(Base) {
     2 
     3     //Base是一个对象
     4     if(isObject(Base)) {
     5 
     6         //Object.create是ES5提出的一种新的对象创建方式,如果存在此方法,则直接返回结果。
     7         if(Object.create)
     8             return Object.create(Base);
     9 
    10         //一个空构造函数,用于构造Sub对象
    11         function Sub() {}
    12 
    13         //将Sub的prototype属性设置为Base,每一个JavaScript的都有这个属性
    14         //Sub便"拥有"Base中的属性和方法,如果Sub还有它的自对象,那属于Sub以
    15         //及Sub父对象的属性和方法也被继承下来,这就是原型链(prototype chain)
    16         Sub.prototype = Base;
    17 
    18         //返回一个Base的子对象,即Sub
    19         return new Sub();
    20     }
    21
    22 }

      3,Eva继承自Person,其中我们通过Eva.name="Eva"给她重新取了个名字,此时程序将打印"Hello, Eva"。(Person.greeting = ...此时写在Person对象里面和外面并无区别,一会在讨论对象的大小时会谈到。)

     1 /**
     2  * Person是一个对象字面量,定义了属性name和方法greeting;
     3  * @type {{name: string, greeting}}
     4  */
     5 var Person = {name:"cnblogs"};
     6 
     7 Person.greeting = function() {
     8     console.log("Hello, " + this.name);
     9 };
    10 
    11 //Eva继承自Person对象,它将Person的属性和方法都继承过来
    12 var Eva = inherit(Person);
    13 
    14 //name继承自Person,将Eva的名字重写为"Eva"
    15 Eva.name = "Eva";
    16 
    17 //greeting继承自Person
    18 Eva.greeting();

      4、更常用和高效的一种方式,此时程序将打印"Hello, John"。

     1 /**
     2  * 通过定义构造器来创建Person2类对象,定义了属性name和原型方法greeting;
     3  * 
     4  * @param name
     5  * @constructor
     6  */
     7 var Person2 = function(name) {
     8     this.name = name;
     9 };
    10 
    11 //"动态"给Person2添加一个greeting方法,此方法并不真正属于Person2,而
    12 //属于Person2.prototype,这样就实现了给Person2及其子类对象添加方法,但
    13 //并不占用多的内存空间。
    14 Person2.prototype.greeting = function() {
    15     console.log("Hello, " + this.name);
    16 };
    17 
    18 var John = inherit(new Person2("John"));
    19 
    20 John.greeting();

      5、此时,如果我们有一个返回对象大小的函数,我们就更能明白prototype在实现继承时是怎么一回事了。

     1 /**
     2  * 返回一个对象的大小(在这里是一个对象真正占有的属性和方法的个数)
     3  * @param object
     4  * @returns {number}
     5  */
     6 function objectSize(object) {
     7 
     8     var size = 0;
     9 
    10     //这里直接使用了Object的hasOwnProperty方法(注意Object是大写)
    11     //Object.prototype.hasOwnProperty = function(propertyName) {};
    12     var hasOwnProperty = Object.prototype.hasOwnProperty;
    13 
    14     //循环遍历object中的所有能"访问"的属性和方法
    15     //注意能"访问"并不等于拥有
    16     for(var key in object) {
    17 
    18         //将hasOwnProperty函数绑定到object(this)上进行调用
    19         //Function.prototype.call = function(thisArg,args) {};
    20         if(hasOwnProperty.call(object, key)) {
    21 
    22             size++;
    23 
    24         }
    25     }
    26     //返回真正属于object的属性和方法个数
    27     return size;
    28 }

      6、所以在实际编程中,往往只将属性写在对象内部,而使用prototype添加各种方法给本对象和子对象使用,但是这些方法在内存中只有一份!(是不是联想到静态成员函数?)

     1 //继承(通过prototype添加)来的不属于我!!
     2 
     3 //程序将打印"2",Person真正拥有name和greeting
     4 console.log("Person size: " + objectSize(Person));
     5 
     6 //程序将打印"1",Eva真正拥有的是重写name属性,如果不重写,将打印"0"
     7 console.log("Eva size: " + objectSize(Eva));
     8 
     9 //程序将打印"1",Person2真正拥有的只是name属性
    10 console.log("Person2 size: " + objectSize(new Person2("John")));
    11 
    12 //程序将打印"0",John啥都没有,都是从"别人"借过来的
    13 console.log("John size: " + objectSize(John));

     未完待续...

  • 相关阅读:
    Oracle基础(五) 权限管理
    Oracle基础(四) 用户管理
    Oracle基础 PL-SQL编程基础(4) 异常处理
    Oracle基础 PL-SQL编程基础(1) 变量和常量
    bash: ifconfig: command not found 问题解决
    chrome innerHTML赋值
    IE下设置body{overflow:hidden;}失效Bug
    EXCEL保存提示“隐私问题警告:此文档中包含宏……”解决办法
    启用SQL Server 2008的专用管理员连接(DAC)
    CSS3 弹性盒模型 box-flex
  • 原文地址:https://www.cnblogs.com/cdefgab1011/p/5308674.html
Copyright © 2020-2023  润新知