zoukankan      html  css  js  c++  java
  • 关于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));

     未完待续...

  • 相关阅读:
    Count and Say leetcode
    Find Minimum in Rotated Sorted Array II leetcode
    Find Minimum in Rotated Sorted Array leetcode
    Search in Rotated Sorted Array II leetcode
    search in rotated sorted array leetcode
    Substring with Concatenation of All Words
    Subsets 子集系列问题 leetcode
    Sudoku Solver Backtracking
    Valid Sudoku leetcode
    《如何求解问题》-现代启发式方法
  • 原文地址:https://www.cnblogs.com/cdefgab1011/p/5308674.html
Copyright © 2011-2022 走看看