• 【js重学系列】原型


    初始

    1. JavaScript 中,万物皆对象!
    2. 但对象也是有区别的。分为普通对象和函数对象,像Object ,Function 是JS自带的函数对象
    3. 怎么区分?其实很简单,凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象。
    4. Function Object 也都是通过 New Function()创建的。

    构造函数

    1. 构造函数可用来创建特定类型的对象。像Object和Array这样的原生构造函数,在运行时会自动出现在执行环境中。

    2. function Person() {
      
      }
      var person = new Person();
      person.name = 'Kevin';
      console.log(person.name) // Kevin
      
    3. 按照国际惯例,构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。

    4. 要创建Person的新实例,必须使用new操作符。一般是经历以下四个步骤:

      1. 创建一个空对象(即{});
      2. 设置原型链(将实例对象的原型对象,指向构造函数的原型对象)
      3. 新创建的对象作为this的上下文 ,只改this指向并且把参数传递过去
      4. 如果是值类型,返回obj。如果是引用类型,就返回这个引用类型的对象

    原型

    1. 无论什么时候,只要创建一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。普通对象没有 prototype,但有 __proto__ 属性。

    2. 如上面例子,Person.prototype 指向了原型象,而 Person.prototype.constructor 又指回了Person。

    3. 而 person 只是一个对象实例。

    4. 而person可以访问保存在原型中的值,但却不能重写原型中的值。如果我们在 person 中添加一个属性,而该属性与实例原型中的一个属性同名,那个person中的属性会暂时屏蔽原型中的属性,删除后,还是读回原型中的属性

    5. function Person() {
      
      }
      Person.prototype.name = 'Perty';
      var person = new Person();
      person.name = 'Kevin';
      console.log(person.name) // Kevin
      delete person.name
      console.log(person.name) // Perty
      
      解析器的操作是:
      
      “实例person有name属性吗?”
      “有” —— 于是就读取实例中的name属性,输出 Kevin
      
      删除后,再运行时:
      
      “实例person有name属性吗?”
      “没有”
      “person的原型有name属性吗?”
      “有” —— 于是就读取原型中的name的属性,输出 Perty
      
    6. ①所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象
      ②所有函数都有一个prototype(原型)属性,属性值是一个普通的对象
      ③所有引用类型的__proto__属性指向构造函数的prototype

    7. var a = [1,2,3];
      a.__proto__ === Array.prototype; // true
      

    原型链

    1. 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做 __proto__ 的内置属性,用于指向创建它的函数对象的原型对象 prototype。以上面的例子为例:

    2. console.log(person.__proto__ === Person.prototype)  *// true*
      
    3. 同样的,Person.prototype 也同样有 proto 属性,它指向创建它的函数对象(Object)的prototype

    4. console.log(Person.prototype.__proto__ === Object.prototype) *// true*
      
    5. 继续,Object.prototype对象也有__proto__属性,但它比较特殊,为nul

    6. console.log(Object.prototype.__proto__) *// null*
      
    7. 我们把这个有 __proto__ 串起来的直到 Object.prototype.__proto__ 为null的链叫做原型链。

    8. person.__proto__ ==> Person.prototype.__proto__ ==> Object.prototype.__proto__ ==> null
      
    9. 当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype__proto__中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链

    10. function Parent(month){
          this.month = month;
      }
      
      var child = new Parent('Ann');
      
      console.log(child.month); // Ann
      
      console.log(child.father); // undefined
      
    11. 在child中查找某个属性时,会执行下面步骤

    12. ①一直往上层查找,直到到null还没有找到,则返回undefined
      Object.prototype.__proto__ === null
      ③所有从原型或更高级原型中的得到、执行的方法,其中的this在执行时,指向当前这个触发事件执行的对象

    链接:

    https://blog.csdn.net/xiaoermingn/article/details/80745117
    https://juejin.cn/post/6844903540943503367
    https://www.jianshu.com/p/ddaa5179cda6
    https://www.jianshu.com/p/dee9f8b14771

  • 相关阅读:
    linux基础_第一篇_IT运维介绍
    Java实现文件分割和文件合并实例
    dotweb——go语言的一个微型web框架(三)路由注册
    dotweb——go语言的一个微型web框架(二)启动dotweb
    dotweb——go语言的一个微型web框架(一)
    Linq的查询操作符
    dsfgdfg
    .NET Entity Framework (with Oracle ODP.NET) -Code First
    .NET Entity Framework (with Oracle ODP.NET)
    ODP.NET 之 ExecuteNoQuery 执行 Merge into 返回值
  • 原文地址:https://www.cnblogs.com/ycyc123/p/14322659.html
Copyright © 2020-2023  润新知