zoukankan      html  css  js  c++  java
  • 理解javascript原型与原型链 Minoz

    想要学习javascript中的面向对象编程(oop),首先就要了解原型及原型链。

    先来个例子,了解原型

    1 function Foo(y){ 
    2 this.y = y; 
    3 } 
    4 Foo.prototype.x = 10; 
    5 Foo.prototype.calculate = function(z){ 
    6 return this.x+this.y+z; 
    7 }; 
    8 var b = new Foo(20); 
    9 alert(b.calculate(30)); 

    js中除了基本数据类型,一切皆对象。那么,对象又是什么意思呢?在我眼里就是键值对的集合。js中几乎所有的对象都有原型(除个别特例)。

    来看上面的例子,构造函数Foo有一个prototype的属性对象,其中prototype属性对象中会包括__proto__,constructor(构造函数)指向构造函数,还有一些添加的属性。

    创建构造函数的实例对象b,b会有__proto__属性(创建一个空函数function a(){}也会包含__proto__属性)指向其原型Foo.prototype。

    Foo.prototype也是一个对象,也存在__proto__属性指向其原型是Object.prototype。

    构造函数Foo也是存在__proto__属性指向它的原型是Function.prototype。

    那么,原型是什么呢?

    我的理解是,原型是构造函数的实例对象的__proto__属性指向的构造函数的prototype属性对象。

    再看个例子,解释一下原型链

     1 function Person(name, age) {
     2     this.name = name;
     3     this.age = age;
     4 }
     5 Person.prototype.hi = function(){
     6     console.log("name" + this.name + '年龄' + this.age);
     7 };
     8 Person.prototype.walk = function() {
     9     console.log(this.name + 'is walking');
    10 };
    11 function Student(name, age, classroom) {
    12     Person.call(this, name, age);
    13     this.classroom = classroom;
    14 }
    15 Student.prototype = Object.create(Person.prototype); 
    16 Student.prototype.constructor = Student;
    17 Student.prototype.hi = function() {
    18     console.log("name" + this.name + '年龄' + this.age + '班级' + this.classroom);
    19 };
    20 var one = new Student('nalixue', '23', '3');
    21 one.walk();
    22 one.hi();

    上面例子中

    创建Person函数,并在Person的原型对象上创建hi和walk函数

    创建Student函数,Student原型对象继承Person的原型对象Student.prototype = Object.create(Person.prototype);并在Student原型对象上覆盖Person的原型对象上的hi

    函数。

    那么,我们创建Student的实例对象one,在调用函数hi()时会在实例本身进行查找,若没有找到,再查找上一级原型,一层一层向上找直到找到为止。

    当找到__proto__属性为null时,证明不存在此方法或属性。这样一层一层查找实例上的原型上的属性就构成一条原型链。

    下面是我画的“十分简易”的原型链:(ps:仅供参考,不提供美观)

    因此调用hi()是Student.prototype上的。

    调用walk()时,实例本身不存在,根据原型链找到Student.prototype也不存在,就继续查找Person.prototype,找到后调用方法。

    如何判断原型呢?

    总共有3种方法

    1 var a = {};
    2 console.log(Object.getPrototypeOf(a));
    3 console.log(a.__proto__);
    4 console.log(a.constructor.prototype);

    以上三种方法皆会输出Object {},可见都可以判断对象上的原型。只不过Object.getPrototypeOf()方法是ECMAScript5新加的,主流浏览才可以用。

    注意:文章最开始提到了js中几乎所有的对象都有原型(除个别特例),那么这个特例是什么呢?

    1 var obj = Object.create(null);
    2 console.log(obj.__proto__);   //undefined

    Object.create()用来创建空对象,此时对象上不存在__pro__属性的。

    PS:顺便说一下,不是所有的函数对象都有prototype属性的

    1 var obj = function() {};
    2 var bind = obj.bind(null);
    3 console.log(bind.prototype);  //undefined

    bind()用来指定运行时的this对象,当为空时,函数对象上就不存在prototype属性。

    不对的地方请多指教~~~~

    参考:

    http://dmitrysoshnikov.com/ecmascript/javascript-the-core/

  • 相关阅读:
    Ecshop商品批量上传,内容编码错误 您尝试查看的页面无法显示
    php 数组转化成字符串,并原样还原回数组
    PHP函数 curl_setopt
    <javascript学习笔记> javascript 获得url里参数。
    <yii 框架学习> <转> 关于yii数据库添加新字段之后model类的修改
    <yii 框架学习> 清空数据表
    <javascript学习笔记>javascript 实现隔行变色
    <javascript学习笔记> javascript 检查输入内容的长度。
    <php 代码积累 数组相关>
    <yii 框架学习> yii 框架改为中文提示
  • 原文地址:https://www.cnblogs.com/nalixueblog/p/4477911.html
Copyright © 2011-2022 走看看