美文网首页
《重学前端》学习笔记(二)

《重学前端》学习笔记(二)

作者: 米开朗基萝 | 来源:发表于2019-02-28 18:28 被阅读0次

    面向对象还是基于对象?

    历史问题

    不同的编程语言中,设计者利用各种不同的语言特性来抽象描述对象,最为成功的流派是使用“类”的方式来描述对象,这诞生了诸如 C++、Java 等流行的编程语言。
    而 JavaScript 早年却选择了一个更为冷门的方式:原型。然而很不幸,因为一些公司政治原因,JavaScript 推出之时受管理层之命被要求模仿 Java,所以,JavaScript 创始人 Brendan Eich 在“原型运行时”的基础上引入了 new、this 等语言特性,使之“看起来更像 Java”。

    JavaScript对象的特征

    1. 对象具有唯一标识性:即使完全相同的两个对象,也并非同一个对象。
    2. 对象有状态:对象具有状态,同一对象可能处于不同状态之下。
    3. 对象具有行为:即对象的状态,可能因为它的行为产生变迁。

    在 JavaScript 中,将状态和行为统一抽象为“属性”。JavaScript中对象具有高度的动态性,这是因为 JavaScript 赋予了使用者在运行时为对象添改状态和行为的能力。

    JavaScript对象的两类属性

    对 JavaScript 来说,属性并非只是简单的名称和值,JavaScript 用一组特征(attribute)来描述属性(property)。

    1. 数据属性
    • value: 属性的值
    • writable: 决定属性都否被赋值
    • enumerable: 决定for in 能否枚举该属性
    • configurable: 决定该属性能否被删除或者改变特征值
    1. 访问器(getter/setter)属性
    • getter: 函数或undefined,在取属性值时被调用
    • setter: 函数或undefined,在设置属性值时被调用
    • enumerable: 决定for in 能否枚举该属性
    • configurable: 决定该属性能否被删除或者改变特征值

    我们通常用于定义属性的代码会产生数据属性,其中的 writable、enumerable、configurable 都默认为 true。我们可以使用内置函数 Object.getOwnPropertyDescripter 来查看:

    var o = { a: 1 };
    o.b = 2;
    //a 和 b 皆为数据属性
    Object.getOwnPropertyDescriptor(o,"a") // {value: 1, writable: true, enumerable: true, configurable: true}
    Object.getOwnPropertyDescriptor(o,"b") // {value: 2, writable: true, enumerable: true, configurable: true}
    

    改变属性特征或者定义访问器属性,可以使用Object.defineProperty

    var o = { a: 1 };
    Object.defineProperty(o, "b", {value: 2, writable: false, enumerable: false, configurable: true});
    //a 和 b 都是数据属性,但特征值变化了
    Object.getOwnPropertyDescriptor(o,"a"); // {value: 1, writable: true, enumerable: true, configurable: true}
    Object.getOwnPropertyDescriptor(o,"b"); // {value: 2, writable: false, enumerable: false, configurable: true}
    o.b = 3;
    console.log(o.b); // 2
    

    什么是原型

    在javaScript之前,原型系统就更多与高动态性语言配合,并且多数基于原型的语言提倡运行时的原型修改,这应该是 Brendan 选择原型系统很重要的理由。

    javaScript原型

    1. 如果所有对象都有私有字段 [[prototype]],就是对象的原型;
    2. 读一个属性,如果对象本身没有,则会继续访问对象的原型,直到原型为空或者找到为止。

    new 运算接受一个构造器和一组调用参数,实际上做了几件事:

    1. 以构造器的 prototype 属性(注意与私有字段 [[prototype]] 的区分)为原型,创建新对象;
    2. 将 this 和调用参数传给构造器,执行;
    3. 如果构造器返回的是对象,则返回,否则返回第一步创建的对象。

    ES6中的类

    基本写法

    class Rectangle {
      constructor(height, width) {
        this.height = height;
        this.width = width;
      }
      // Getter
      get area() {
        return this.calcArea();
      }
      // Method
      calcArea() {
        return this.height * this.width;
      }
    }
    
    

    继承能力

    class Animal { 
      constructor(name) {
        this.name = name;
      }
      
      speak() {
        console.log(this.name + ' makes a noise.');
      }
    }
    
    class Dog extends Animal {
      constructor(name) {
        super(name); // call the super class constructor and pass in the name parameter
      }
    
      speak() {
        console.log(this.name + ' barks.');
      }
    }
    
    let d = new Dog('Mitzie');
    d.speak(); // Mitzie barks.
    
    

    相关文章

      网友评论

          本文标题:《重学前端》学习笔记(二)

          本文链接:https://www.haomeiwen.com/subject/avmkuqtx.html