设置原型属性
通过proto设置,不好
function Person() {this.name = 'zhangsan';this.age = '18';}var person = new Person();person.__proto__={a:1}/*访问慢,性能不好,这样写影响所有在__proto__上面的所有原型对象,* 虽然浏览器都支持这种写法,但他是内部属性,不可访问,并且有种种缺点*//*1语义化,内部属性;* 2访问效率慢;* 3所有继承自该原型的对象都会影响到;*/console.log(person);// console.log(Object.prototype);

setPrototypeOf设置原型
用这些方法修改原型
Object.setPrototypeOf();//(写的操作)Object.getPrototypeOf();//(读取操作)Object.create();//(生成操作)
修改obj,obj的原型变成proto对象
let proto = {y: 20,z: 40}let obj = {x: 10};let obj1 = Object.setPrototypeOf(obj, proto);console.log(obj===obj1);//true

原始值无法设置对象,没有设置成功
setPrototypeOf只要传的第一个值不是对象,不会有任何效果,绑定失效了,还是返回1
getPrototypeOf访问原型会变成包装类,new Number(1).prototype
let obj = Object.setPrototypeOf(1, {a: 1, b: 2});console.log(obj);//1console.log(Object.getPrototypeOf(obj));console.log(Object.getPrototypeOf(1)===Number.prototype);//true

不会变成包装类,与下面代码不一样
let obj = Object.setPrototypeOf(new Number(1), {a: 1, b: 2});console.log(obj);//1console.log(Object.getPrototypeOf(obj));

let obj = Object.setPrototypeOf('foo', {a: 1, b: 2});console.log(obj);//fooconsole.log(Object.getPrototypeOf('foo')===String.prototype);//true
let obj = Object.setPrototypeOf(true, {a: 1, b: 2});console.log(obj);//trueconsole.log(Object.getPrototypeOf(true)===Boolean.prototype);//true
null、undefined失败
let obj = Object.setPrototypeOf(undefined, {a: 1, b: 2});console.log(obj);//Uncaught TypeError: Object.setPrototypeOf called on null or undefined
let obj = Object.setPrototypeOf(null, {a: 1, b: 2});console.log(obj);//Uncaught TypeError: Object.setPrototypeOf called on null or undefined
keys、values、entries
enumerable : true时,才可以遍历
const foo = {a: 1,b: 2,c: 3}Object.defineProperties(foo,{d : {value :4,enumerable : true},f:{value : 5,enumerable:false}})console.log(Object.keys(foo));//['a', 'b', 'c', 'd']/*自身的可枚举的键名*/console.log(Object.values(foo));//[1, 2, 3, 4]/*自身的可以枚举的键名,对应的属性值*/console.log(Object.entries(foo));/*自身的可以枚举的键名,对应的键名:属性值*/

d=4并没有取到,没有被keys遍历到
const foo = {a:1,b:2,c:3}Object.defineProperty(Object.prototype, 'd', {value:4,writable:true,enumerable:true,configurable:true})console.log(foo);//{a: 1, b: 2, c: 3}var arr = Object.keys(foo);console.log(arr);//['a', 'b', 'c']

三个方法都不能遍历原型上面的内容,属性
const foo = {a:1,b:2,c:3}Object.defineProperty(Object.prototype, 'd', {value:4,writable:true,enumerable:true,configurable:true})/* console.log(foo);//{a: 1, b: 2, c: 3}var arr = Object.keys(foo);console.log(arr);//['a', 'b', 'c']*/console.log(Object.keys(foo));//['a', 'b', 'c']console.log(Object.values(foo));//[1, 2, 3]console.log(Object.entries(foo));

包装类
var obj={};var obj=1;var obj=true;// var obj={};console.log(Object.keys({}));//[]console.log(Object.keys(1));//[]console.log(Object.keys(true));//[]
console.log(Object.keys('123'));//['0', '1', '2']console.log(Object.values('123'));//['1', '2', '3']console.log(Object.entries('123'));//[Array(2), Array(2), Array(2)]

super
super(指向的是对象的原型对象) —->this;
this有自己的原意,比如说它指向的是当前对象本身,
super也有自己的原意,父类,指向的是对象的原型对象
let proto = {y: 20,z: 40}let obj = {x: 10}Object.setPrototypeOf(obj,proto);console.log(obj);

let proto = {y: 20,z: 40}let obj = {x: 10,foo:super.y}Object.setPrototypeOf(obj,proto);//Uncaught SyntaxError: 'super' keyword unexpected hereconsole.log(obj);
依然报错,foo箭头函数也会报错
函数、箭头函数都会报错
let proto = {y: 20,z: 40}let obj = {x: 10,// foo:super.y,/* foo:function() {console.log(super.y);// Uncaught SyntaxError: 'super' keyword unexpected here}*/foo :()=>{console.log(super.y);// Uncaught SyntaxError: 'super' keyword unexpected here}}Object.setPrototypeOf(obj,proto);console.log(obj);
let proto = {y: 20,z: 40}let obj = {x: 10,foo() {console.log(super.y);//对象的简写的写法才能生效;}}Object.setPrototypeOf(obj, proto);obj.foo();//20
let proto = {y: 20,z: 40,bar:function() {console.log(this.y);}}let obj = {x: 10,foo() {// console.log(super.y);//对象的简写的写法才能生效;super.bar();}}Object.setPrototypeOf(obj, proto);obj.foo();//20
也没有问题,通过super调用方法
symbol
变量不重名可以通过let、const来定义,但对象里的属性不能通过let、const,可能会重名
symbol是一个原始值的类型
原始值类型的值
string number,boolean,null,undefined、symbol
引用值 Object、array、function
Symbol不是构造函数
Symbol不是构造函数Function,new 会报错,它是原始值,肯定不是构造函数function
console.log(new Symbol());//TypeError: Symbol is not a constructor
console.log(Symbol());//Symbol()
所有Symbol值都不一样
都不一样
let s1=Symbol();let s2=Symbol();console.log(s1===s2);//falseconsole.log(typeof s1);//symbolconsole.log(typeof(s1));//symbol
不能挂载属性
挂不上属性
let s1=Symbol();s1.a=1;console.log(s1.a);//undefined
symbol是唯一的,那怎么找到它,通过传入参数,怎么区分不同的symbol的值,通过传参数
symbol本身值都是不一样的,传不传参数不影响,但想要找到,而不是赋予let xx=symbol,用xx,这时就需要参数了,参数就是数据,用参数区分,用数据查找
可以通过不同的参数,识别不同的symbol类型的值
let s1=Symbol('foo');console.log(s1);//Symbol(foo)s1.a=1;console.log(s1.a);//undefined

会隐式转换成字符串
var obj = {a: 1};let s1=Symbol(obj);console.log(Object.prototype.toString.call(obj));//[object Object]console.log(s1);//Symbol([object Object])
var obj = {a: 1};// var s1=Symbol(null);///Symbol(null)var s1=Symbol(undefined);//Symbol() 没有不是Symbol(undefined)console.log(s1);
不能转换成数字
let s1=Symbol(null);console.log(s1+1);//TypeError: Cannot convert a Symbol value to a number
let s1=Symbol(null);console.log(Object.getPrototypeOf(s1));// console.log(s1+1);//TypeError: Cannot convert a Symbol value to a number// console.log(Number(s1))//TypeError: Cannot convert a Symbol value to a numberconsole.log(String(s1));//Symbol(null)console.log(Boolean(s1));//true 只有Number不能转;
主要是以下三个方法
let s1=Symbol(null);console.log(Object.getPrototypeOf(s1));

tostring方法
这个东西不太难,但知识点有点散,视频中是总结的,需要、应该对着视频把知识难点,知识点都给列下来,视频是保证听懂的,保证理解的,看视频理解知识点,把理解的知识点做成笔记,看视频听懂,必须做笔记,把知识点列下来,记录
let s1=Symbol(null);console.log(s1.toString());//Symbol(null)
let s1=Symbol(null);console.log(!s1);//falseconsole.log(s1+'');//TypeError: Cannot convert a Symbol value to a string/*不能通过隐式转换,可以显示转换* 唯一可以隐式转换的是取反!s1,不报错,其它都报错,隐式转换仅限于Boolean*/console.log(s1.toString());//Symbol(null)
let name=Symbol();let person={};person.name='zhangsan';/*.name自动转换成字符串,就不能用,想用name变量需要[]*/console.log(person['name']);//zhangsan
let name=Symbol();let person={};person[name]='zhangsan';console.log(person);//{ [Symbol()]: 'zhangsan' }
let name=Symbol();let person={[name]:'zhangsan'};console.log(person);//{ [Symbol()]: 'zhangsan' }
let name=Symbol();let person={};Object.defineProperty(person,name,{value:'zhangsan'})console.log(person[name])//console.log(person)//{}设置在原型上面了
[]与symbol
let name=Symbol();let eat=Symbol();let person={[name]:'zhangsan',[eat](){console.log(this[name])}}person[eat]();//zhangsan
for、keyfor
symbol与构造函数
console.log(Symbol);//ƒ Symbol() { [native code] }console.log(Symbol());//Symbol()/*Symbol比较奇怪,是构造函数,但是不能new,只能通过方法执行的方式来运行*/
这是顶层定义的,顶层是c++等,底层定义时就这样定义的
以后行不行不知道,现在不行
for
Symbo.for(key键名,标识符:类型字符串)
返回值与Symbol()一样返回Symbol类型的值
Symbol永远拿到的是不一样的字符串,独一无二symbol类型的值
let s1=Symbol('foo');let s2=Symbol('foo');console.log(s1===s2);//false
如果就想拿到一样的值,该怎么办?
/*s1的时候,找key值为foo的symbol存不存在,不存在,新建* s2时时候,找key值为foo的symbol存不存在,存在,找之前声明过的symbol值*/let s=Symbol('foo');let s1=Symbol.for('foo');let s2=Symbol.for('foo');console.log(s1===s2);//true
keyfor
Symbo.keyfor(Symbol1,Symbol类型的值:类型Symbol)
作用:查找Symbol是的键值,并返回
返回值:Symbol的键值:字符串
let s=Symbol('foo');let s1=Symbol.for('foo');let s2=Symbol.for('foo');console.log(s1===s2);//trueconsole.log(Symbol.keyFor(s1));//fooconsole.log(Symbol.keyFor(s1)===Symbol.keyFor(s2));//trueconsole.log(Symbol.keyFor(s));//undefined/*s并没有传key值,不是Symbol.for方法创造出来的*/
不能遍历Symbol属性的值
const obj={};let a=Symbol('a');let b=Symbol('b');obj[a]='hello';obj[b]='world';obj.c='1';for (let i in obj) {/*只打印c的值,不会打印三个属性* for in不能遍历 Symbol属性的对象;*/console.log(i);//cconsole.log(obj[i]);//1console.log('run')//run}
const obj={};let a=Symbol('a');let b=Symbol('b');obj[a]='hello';obj[b]='world';obj.c='1';for (let i in obj) {/*只打印c的值,不会打印三个属性* for in不能遍历 Symbol属性的对象;*/console.log(i);//cconsole.log(obj[i]);//1console.log('run')//run}for (let i of obj) {//TypeError: obj is not iterableconsole.log(i);}
const obj={};let a=Symbol('a');let b=Symbol('b');obj[a]='hello';obj[b]='world';obj.c='1';for (let i in obj) {/*只打印c的值,不会打印三个属性* for in不能遍历 Symbol属性的对象;*/console.log(i);//cconsole.log(obj[i]);//1console.log('run')//run}/*for (let i of obj) {//TypeError: obj is not iterableconsole.log(i);}*/var obj1={};Object.assign(obj1,obj);console.log(obj1);//{ c: '1', [Symbol(a)]: 'hello', [Symbol(b)]: 'world' }/*可以被assign合并,但还是不能遍历合并的obj1,就想遍历怎么办?*/
getOwnPropertySymbols
var obj1={};Object.assign(obj1,obj);console.log(obj1);//{ c: '1', [Symbol(a)]: 'hello', [Symbol(b)]: 'world' }/*可以被assign合并,但还是不能遍历合并的obj1,就想遍历怎么办?*/const objectSymbols=Object.getOwnPropertySymbols(obj);/*只会遍历obj中Symbol属性的值*/console.log(objectSymbols);//[ Symbol(a), Symbol(b) ]
const obj = {c: 1, d: 2};let a = Symbol('a');let b = Symbol('b');let _a = Symbol('_a');let _b = Symbol('_b');obj[a] = 'hello';obj[b] = 'world';Object.defineProperties(obj, {e: {value: 5,enumerable: true},f: {value: 6,enumerable: false},[_a]: {value: -1,enumerable: true},[_b]: {value: -2,enumerable: false}})let h = Symbol('h');let i = Symbol('i');let j = Symbol('j');const obj1 = {g: 7,[h]: 8}Object.defineProperties(obj1, {[i]: {value: 9,enumerable: true},[j]: {value: 10},k: {value: 11}})Object.setPrototypeOf(obj, obj1);console.log(obj);console.log('--------')for (let i in obj) {console.log(i);}console.log('--------')console.log(Object.keys(obj));console.log('--------')console.log(Object.getOwnPropertySymbols(obj));

解析
const obj = {c: 1, d: 2};let a = Symbol('a');let b = Symbol('b');let _a = Symbol('_a');let _b = Symbol('_b');obj[a] = 'hello';obj[b] = 'world';Object.defineProperties(obj, {e: {value: 5,enumerable: true},f: {value: 6,enumerable: false},[_a]: {value: -1,enumerable: true},[_b]: {value: -2,enumerable: false}})let h = Symbol('h');let i = Symbol('i');let j = Symbol('j');const obj1 = {g: 7,[h]: 8}Object.defineProperties(obj1, {[i]: {value: 9,enumerable: true},[j]: {value: 10},k: {value: 11}})Object.setPrototypeOf(obj, obj1);console.log(obj);console.log('--------')/*for in遍历自身和继承的可枚举属性(不包含Symbol类型的值);*/for (let i in obj) {console.log(i);}console.log('--------')console.log(Object.keys(obj));/*遍历自身可枚举的属性,不包含Symbol类型的值,需要可以枚举* 不包含继承*/console.log('--------')console.log(Object.getOwnPropertySymbols(obj));/*遍历自身Symbol上面的值,不需要可枚举,不可枚举的,也可以遍历*/var obj3 = {};Object.assign(obj3, obj);/*遍历自身可枚举的,包含symbol类型值的*/console.log(obj3)JSON.stringify()/*遍历自身可枚举的,不包含symbol*/

