javascript高级程序阅读收获(8.4.3)——实例、原型和类成员

1.实例成员

class Person{
	constructor(){
		this.name = new String('Jack');
		this.sayName = () => console.log(this.name);
		this.nicknames = ['Jake','J-Dog']
	}
}

let p1 = new Person(),
	p2 = new Person();

p1.sayName();
p2.sayName();

console.log(p1.name === p2.name);//false
console.log(p1.sayName === p2.sayName);//false
console.log(p1.nicknames === p2.nicknames);//false

p1.name = p1.nicknames[0];
p2.name = p2.nicknames[1];
p1.sayName();//Jack
p2.sayName();//J-Dog
  1. 在构造函数内部,可以为新创建的实例添加“自有属性”。
  2. 构造函数执行完毕后,仍然可以给实例继续添加新成员。
  3. 每个实例都对应一个唯一的成员对象,这意味着所有成员都不会在原型上共享。

2.原型方法与访问器

class Person{
	constructor(){
		this.locate = () => console.log('instance');
	}
	locate(){
		console.log('prototype');
	}
}
let p = new Person();
p.locate();//instance
p.prototype.locate();//prototype
  1. 添加到this中的内容会存在于不同的实例上。
  2. 在类中定义的所有内容都会定义在类的原型上。
class Person{
	name:"Jake"
}//Uncaught SyntaxError:Unexpected token
  1. 可以把方法定义在类构造函数中或则类块中,但不能在类块中给原型添加原始值或对象作为成员数据。
const symbolKey = Symbol('symbolKey');
class Person{
	stringKey(){
		console.log('invoked stringKey');
	}
	[symbolKey](){
		console.log('invoked symbolKey');
	}
	['computed'+'Key'](){
		console.log('invoked computedKey');
	}
}
let p = new Person();
p.stringKey();//invoked stringKey
p[symbolKey]();//invoked symbolKey
p.computedKey();//invoked computedKey
  1. 类方法等同于对象属性,因此可以使用字符串、符号或计算的值作为键。
class Person{
	set name(newName){
		this.name_ = newName;
	}
	get name(){
		return this.name_;
	}
}

let p = new Person();
p.name = 'Jake';
console.log(p.name);//Jake
  1. 类定义也支持获取和设置访问器,语法与行为跟普通对象一样。

3.静态类方法

class Person{
	constructor(){
		this.locate = () => console.log('instance',this);
	}
	
	locate(){
		console.log('prototype',this);
	}

	static locate(){
		console.log("class",this);
	}
}

let p = new Person();
p.locate();//instance Person {locate: ƒ}
Person.prototype.locate();//prototype {constructor: ƒ, locate: ƒ}
Person.locate();//class class Person{……}
  1. 静态类成员在类定义中使用static关键字作为前缀。在静态成员中,this引用类自身。其他所有约定跟原型成员一样。

4.非函数原型和类成员

class Person{
	sayName(){
		console.log(`${Person.greeting} ${this.name}`)
	}
}

Person.greeting = "My name is ";//在类上定义数据成员
Person.prototype.name = "Jake";//在原型上定义数据成员

let p = new Person();
p.sayName();//My name is  Jake
  1. 虽然类定义并不显示支持在原型或类上添加成员数据,但在类定义外部,可以手动添加。
  2. 类定义中之所以没有显示支持添加数据成员,是因为在共享目标(原型和类)上添加可变(可修改)数据成员是一种反模式。一般来说,对象实例应该独自拥有通过this引用的数据。

5.迭代器与生成器方法

class Person {
	//在原型上定义生成器方法
	*createNicknameIterator(){
		yield 'Jack';
		yield 'Jake';
		yield 'J-Dog';
	}
	//在类上定义生成器方法
	static *createJobIterator(){
		yield 'Butcher';
		yield 'Baker';
		yield 'Candlestick maker';
	}
}

let jobIter = Person.createJobIterator();
console.log(jobIter.next().value);//Jack
console.log(jobIter.next().value);//Jake
console.log(jobIter.next().value);//J-Dog

let p = new Person();
let nicknameIter = p.createNicknameIterator();
console.log(nicknameIter.next().value);//Butcher
console.log(nicknameIter.next().value);//Baker
console.log(nicknameIter.next().value);//Candlestick maker
  1. 类定义语法支持在原型和类本身上定义生成器方法。
class Person{
	constructor(){
		this.nicknames = ['Jack','Jake','J-Dog'];
	}

	*[Symbol.iterator](){
		yield *this.nicknames.entries();
	}
}

let p = new Person();
for(let [idx,nickname] of p){
	console.log(nickname);
}
//Jack
//Jake
//J-Dog
  1. 可以通过添加一个默认的迭代器,把类实例变成可迭代对象。
上一篇:php 创建多级文件夹


下一篇:linux中查找(find、locate、which、whereis、grep)命令汇总、帮助命令(man、whatis、apropos、info、help)汇总