阿尔卑斯丶
圣骑士
圣骑士
  • 最后登录2023-11-03
  • 发帖数59
  • 社区居民
  • 原创写手
阅读:1740回复:0

[es 6]JavaScript对象:我们真的需要模拟类吗

楼主#
更多 发布于:2022-01-04 17:08
1、什么是原型?
答:“照猫画虎”,这里的猫就是虎的原型。JavaScript是利用原型来描述对象。
2、什么是基于原型?
答:基于原型的面向对象系统是通过“复制”的方式来创建新对象。这种操作有两种实现思路:
一是并不是真的去复制一个原型对象,而是使得新对象持有一个原型的引用;
另一个是切实地复制对象,从此两个对象再无联系。
显然,JavaScript使用了第一种方式。
3、JavaScript的原型
答:简单概括就是:
如果所有对象都有私有字段[[prototype]],就是对象的原型;
读一个属性,如果对象本身没有,则会继续访问对象后的原型,知道原型为空或者找到为止。
4、ES6提供的内置函数,方便直接访问操纵原型:
答:Object.create 根据指定的原型创建新对象,原型可以是 null;
Object.getPrototypeOf 获得一个对象的原型;
Object.setPrototypeOf 设置一个对象的原型。
var cat = {
    say(){
        console.log("meow~");
    },
    jump(){
        console.log("jump");
    }
}
var tiger = Object.create(cat,  {
    say:{
        writable:true,
        configurable:true,
        enumerable:true,
        value:function(){
            console.log("roar!");
        }
    }
})
var anotherCat = Object.create(cat);
anotherCat.say();
var anotherTiger = Object.create(tiger);
anotherTiger.say();

这段代码创建了一个“猫”对象,又根据猫做了一些修改创建了虎,之后我们完全可以用 Object.create 来创建另外的猫和虎对象,我们可以通过“原始猫对象”和“原始虎对象”来控制所有猫和虎的行为。
5、那虎这个类的say方法里怎么取调用猫的say方法呢?是不是在方法里实例一个猫对象去掉用猫.say()?这样一来就多生产一个对象了。如果继承有很多层的会多出很多实例呢?
答:Object.getPrototypeOf(Object.getPrototypeOf(anotherTiger)).say();
6、早期版本中的类与原型。
答:在早期版本的 JavaScript 中,“类”的定义是一个私有属性 [[class]],语言标准为内置类型诸如 Number、String、Date 等指定了[[class]]属性,以表示它们的类。语言使用者唯一 可以访问[[class]]属性的方式是 Object.prototype.toString。
7、为什么object.prototype.tostring是最准确的判断数据的方法。
答:js中私有属性不可更改,且只有这个方法可以访问。
8、以下代码展示了所有具有内置 class 属性的对象:

9、new操作具体做了哪些操作?
答:new 运算接受一个构造器和一组调用参数,实际上做了几件事:
以构造器的 prototype 属性(注意与私有字段[[prototype]]的区分)为原型,创建新对象;
将 this 和调用参数传给构造器,执行;
如果构造器返回的是对象,则返回,否则返回第一步创建的对象。
new 这样的行为,试图让函数对象在语法上跟类变得相似,但是,它客观上提供了两种方式,一是在构造器中添加属性,二是在构造器的 prototype 属性上添加属性。
10、下面的代码展示了使用构造器来模拟类的两种方法:
function c1(){
    this.p1 = 1;
    this.p2 = function(){
        console.log(this.p1);
    }
} 
var o1 = new c1;
o1.p2();
function c2(){
}
c2.prototype.p1 = 1;
c2.prototype.p2 = function(){
    console.log(this.p1);
}
var o2 = new c2;
o2.p2();

第一种方法是直接在构造器中修改 this,给 this 添加属性。
第二种方法是修改构造器的 prototype 属性指向的对象,它是从这个构造器构造出来的所有对象的原型。
11、ES6中的类
答:ES6中新特性class关键字,类的概念正是从属性升级为语言的基础设施。类的编程方式成为了JavaScript的官方编程范式。
类的基本写法:
class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
  // Getter
  get area() {
    return this.calcArea();
  }
  // Method
  calcArea() {
    return this.height * this.width;
  }
}

我们通过 get/set 关键字来创建 getter,通过括号和大括号来创建方法,数据型成员最好写在构造器里面。不建议在constructor之外定义属性。
12、类的写法实际上是有原型运行时来承载的,逻辑上JavaScript认为每个类是有共同原型 的一组对象,类中定义的属性和方法会被写在原型对象之上。
最重要的是,类提供了继承能力。
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.

super() 实际上相当于Parent.prototype.constructor.call(this)
使用 extends 关键字自动设置了 constructor,并且会自动调用父类的构造函数,这是一种更少坑的设计。
游客


返回顶部

公众号

公众号