Encapsulation(封装)

Properties that are part of the interface are called public. The others, which outside code should not be touching, are called private.

Many languages provide a way to distinguish public and private properties and prevent outside code from accessing the private ones altogether.JavaScript, once again taking the minimalist approach, does not—not yet at least.

It is also common to put an underscore (_) character at the start of property names to indicate that those properties are private.

Separating interface from implementation is a great idea. It is usually called encapsulation.

Methods

Methods are nothing more than properties that hold function values.
object.method()—the binding called this in its body automatically points at the object that it was called on.

  1. function speak(line) {
  2. console.log(`The ${this.type} rabbit says '${line}'`);
  3. }
  4. let whiteRabbit = {type: "white", speak};
  5. let hungryRabbit = {type: "hungry", speak};
  6. whiteRabbit.speak("Oh my ears and whiskers, " +
  7. "how late it's getting!");
  8. // → The white rabbit says 'Oh my ears and whiskers, how
  9. // late it's getting!'
  10. hungryRabbit.speak("I could use a carrot right now.");
  11. // → The hungry rabbit says 'I could use a carrot right now.'

you can use a function’s call method, which takes the this value as its first argument and treats further arguments as normal parameters.

  1. speak.call(hungryRabbit, "Burp!");
  2. // → The hungry rabbit says 'Burp!'

Arrow functions are different—they do not bind their own this but can see the this binding of the scope around them.

  1. function normalize() {
  2. console.log(this.coords.map(n => n / this.length));
  3. }
  4. normalize.call({coords: [0, 2, 3], length: 5});
  5. // → [0, 0.4, 0.6]

Prototypes

Object.getPrototypeOf()查看一个对象的proto

  1. console.log(Object.getPrototypeOf({}) ==
  2. Object.prototype);
  3. // → true
  4. console.log(Object.getPrototypeOf(Object.prototype));
  5. // → null

You can use Object.create to create an object with a specific prototype.

  1. let protoRabbit = {
  2. speak(line) {
  3. console.log(`The ${this.type} rabbit says '${line}'`);
  4. }
  5. };
  6. let killerRabbit = Object.create(protoRabbit);
  7. killerRabbit.type = "killer";
  8. killerRabbit.speak("SKREEEE!");
  9. // → The killer rabbit says 'SKREEEE!'
  10. killerRabbit.__proto__ === protoRabbit
  11. // true
  12. protoRabbit.__proto__ === Object.prototype
  13. // true

Classes

A class defines the shape of a type of object—what methods and properties it has. Such an object is called an instance of the class.

constructor function

  1. function makeRabbit(type) {
  2. let rabbit = Object.create(protoRabbit);
  3. rabbit.type = type;
  4. return rabbit;
  5. }

JavaScript provides a way to make defining this type of function easier. If you put the keyword new in front of a function call, the function is treated as a constructor. This means that an object with the right prototype is automatically created, bound to this in the function, and returned at the end of the function.

  1. function Rabbit(type) {
  2. this.type = type;
  3. }
  4. Rabbit.prototype.speak = function(line) {
  5. console.log(`The ${this.type} rabbit says '${line}'`);
  6. };
  7. let weirdRabbit = new Rabbit("weird");
  8. Rabbit.__proto__ === Function.prototype
  9. // true
  10. weirdRabbit.__proto__ === Rabbit.prototype
  11. // true

So JavaScript classes are constructor functions with a prototype property. until 2015.

Class notation

  1. class Rabbit {
  2. constructor(type) {
  3. this.type = type;
  4. }
  5. /* 目前只能将method写到prototype,不能写property */
  6. speak(line) {
  7. console.log(`The ${this.type} rabbit says '${line}'`);
  8. }
  9. }
  10. let killerRabbit = new Rabbit("killer");
  11. let blackRabbit = new Rabbit("black");

class也可以直接用于表达式

  1. let object = new class { getWord() { return "hello"; } };
  2. console.log(object.getWord());
  3. // → hello

override 重写

  1. Rabbit.prototype.teeth = "small";
  2. console.log(killerRabbit.teeth);
  3. // → small
  4. killerRabbit.teeth = "long, sharp, and bloody";
  5. console.log(killerRabbit.teeth);
  6. // → long, sharp, and bloody
  7. console.log(blackRabbit.teeth);
  8. // → small
  9. console.log(Rabbit.prototype.teeth);
  10. // → small

Eloquent JavaScript(chapter 6) - 图1

maps

in 操作符会访问Object的prototype的属性,用hasOwnProperty只访问对象本身属性

  1. console.log("toString" in {})
  2. // true
  3. console.log({x: 1}.hasOwnProperty("x"));
  4. // → true
  5. console.log({x: 1}.hasOwnProperty("toString"));
  6. // → false

map

  1. let ages = new Map();
  2. ages.set("Boris", 39);
  3. ages.set("Liang", 22);
  4. ages.set("Júlia", 62);
  5. console.log(`Júlia is ${ages.get("Júlia")}`);
  6. // → Júlia is 62
  7. console.log("Is Jack's age known?", ages.has("Jack"));
  8. // → Is Jack's age known? false
  9. console.log(ages.has("toString"));
  10. // → false

Polymorphism 多态

When you call the String function (which converts a value to a string) on an object, it will call the toString method on that object to try to create a meaningful string from it.

  1. Rabbit.prototype.toString = function() {
  2. return `a ${this.type} rabbit`;
  3. };
  4. console.log(String(blackRabbit));
  5. // → a black rabbit

Symbols

Unlike strings, newly created symbols are unique—you cannot create the same symbol twice.

  1. let sym = Symbol("name");
  2. console.log(sym == Symbol("name"));
  3. // → false
  4. Rabbit.prototype[sym] = 55;
  5. console.log(blackRabbit[sym]);
  6. // → 55
  1. const toStringSymbol = Symbol("toString");
  2. Array.prototype[toStringSymbol] = function() {
  3. return `${this.length} cm of blue yarn`;
  4. };
  5. console.log([1, 2].toString());
  6. // → 1,2
  7. console.log([1, 2][toStringSymbol]());
  8. // → 2 cm of blue yarn

instanceof

  1. console.log(
  2. new SymmetricMatrix(2) instanceof SymmetricMatrix);
  3. // → true
  4. console.log(new SymmetricMatrix(2) instanceof Matrix);
  5. // → true
  6. console.log(new Matrix(2, 2) instanceof SymmetricMatrix);
  7. // → false
  8. console.log([1] instanceof Array);
  9. // → true