设置原型属性

通过proto设置,不好

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

image.png

setPrototypeOf设置原型

用这些方法修改原型

  1. Object.setPrototypeOf();//(写的操作)
  2. Object.getPrototypeOf();//(读取操作)
  3. Object.create();//(生成操作)

修改obj,obj的原型变成proto对象

  1. let proto = {
  2. y: 20,
  3. z: 40
  4. }
  5. let obj = {x: 10};
  6. let obj1 = Object.setPrototypeOf(obj, proto);
  7. console.log(obj===obj1);//true

image.png

原始值无法设置对象,没有设置成功
setPrototypeOf只要传的第一个值不是对象,不会有任何效果,绑定失效了,还是返回1
getPrototypeOf访问原型会变成包装类,new Number(1).prototype

  1. let obj = Object.setPrototypeOf(1, {a: 1, b: 2});
  2. console.log(obj);//1
  3. console.log(Object.getPrototypeOf(obj));
  4. console.log(Object.getPrototypeOf(1)===Number.prototype);//true

image.png

不会变成包装类,与下面代码不一样

  1. let obj = Object.setPrototypeOf(new Number(1), {a: 1, b: 2});
  2. console.log(obj);//1
  3. console.log(Object.getPrototypeOf(obj));

image.png

  1. let obj = Object.setPrototypeOf('foo', {a: 1, b: 2});
  2. console.log(obj);//foo
  3. console.log(Object.getPrototypeOf('foo')===String.prototype);//true
  1. let obj = Object.setPrototypeOf(true, {a: 1, b: 2});
  2. console.log(obj);//true
  3. console.log(Object.getPrototypeOf(true)===Boolean.prototype);//true

null、undefined失败

  1. let obj = Object.setPrototypeOf(undefined, {a: 1, b: 2});
  2. console.log(obj);//Uncaught TypeError: Object.setPrototypeOf called on null or undefined
  1. let obj = Object.setPrototypeOf(null, {a: 1, b: 2});
  2. console.log(obj);//Uncaught TypeError: Object.setPrototypeOf called on null or undefined

keys、values、entries

enumerable : true时,才可以遍历

  1. const foo = {
  2. a: 1,
  3. b: 2,
  4. c: 3
  5. }
  6. Object.defineProperties(foo,{
  7. d : {
  8. value :4,
  9. enumerable : true
  10. },
  11. f:{
  12. value : 5,
  13. enumerable:false
  14. }
  15. })
  16. console.log(Object.keys(foo));//['a', 'b', 'c', 'd']
  17. /*自身的可枚举的键名*/
  18. console.log(Object.values(foo));//[1, 2, 3, 4]
  19. /*自身的可以枚举的键名,对应的属性值*/
  20. console.log(Object.entries(foo));
  21. /*自身的可以枚举的键名,对应的键名:属性值*/

image.png

d=4并没有取到,没有被keys遍历到

  1. const foo = {
  2. a:1,
  3. b:2,
  4. c:3
  5. }
  6. Object.defineProperty(Object.prototype, 'd', {
  7. value:4,
  8. writable:true,
  9. enumerable:true,
  10. configurable:true
  11. })
  12. console.log(foo);//{a: 1, b: 2, c: 3}
  13. var arr = Object.keys(foo);
  14. console.log(arr);//['a', 'b', 'c']

image.png

三个方法都不能遍历原型上面的内容,属性

  1. const foo = {
  2. a:1,
  3. b:2,
  4. c:3
  5. }
  6. Object.defineProperty(Object.prototype, 'd', {
  7. value:4,
  8. writable:true,
  9. enumerable:true,
  10. configurable:true
  11. })
  12. /* console.log(foo);//{a: 1, b: 2, c: 3}
  13. var arr = Object.keys(foo);
  14. console.log(arr);//['a', 'b', 'c']*/
  15. console.log(Object.keys(foo));//['a', 'b', 'c']
  16. console.log(Object.values(foo));//[1, 2, 3]
  17. console.log(Object.entries(foo));

image.png

包装类

  1. var obj={};
  2. var obj=1;
  3. var obj=true;
  4. // var obj={};
  5. console.log(Object.keys({}));//[]
  6. console.log(Object.keys(1));//[]
  7. console.log(Object.keys(true));//[]
  1. console.log(Object.keys('123'));//['0', '1', '2']
  2. console.log(Object.values('123'));//['1', '2', '3']
  3. console.log(Object.entries('123'));//[Array(2), Array(2), Array(2)]

image.png

super

super(指向的是对象的原型对象) —->this;
this有自己的原意,比如说它指向的是当前对象本身,
super也有自己的原意,父类,指向的是对象的原型对象

  1. let proto = {
  2. y: 20,
  3. z: 40
  4. }
  5. let obj = {
  6. x: 10
  7. }
  8. Object.setPrototypeOf(obj,proto);
  9. console.log(obj);

image.png

  1. let proto = {
  2. y: 20,
  3. z: 40
  4. }
  5. let obj = {
  6. x: 10,
  7. foo:super.y
  8. }
  9. Object.setPrototypeOf(obj,proto);
  10. //Uncaught SyntaxError: 'super' keyword unexpected here
  11. console.log(obj);

依然报错,foo箭头函数也会报错
image.png

函数、箭头函数都会报错

  1. let proto = {
  2. y: 20,
  3. z: 40
  4. }
  5. let obj = {
  6. x: 10,
  7. // foo:super.y,
  8. /* foo:function() {
  9. console.log(super.y);
  10. // Uncaught SyntaxError: 'super' keyword unexpected here
  11. }*/
  12. foo :()=>{
  13. console.log(super.y);
  14. // Uncaught SyntaxError: 'super' keyword unexpected here
  15. }
  16. }
  17. Object.setPrototypeOf(obj,proto);
  18. console.log(obj);
  1. let proto = {
  2. y: 20,
  3. z: 40
  4. }
  5. let obj = {
  6. x: 10,
  7. foo() {
  8. console.log(super.y);
  9. //对象的简写的写法才能生效;
  10. }
  11. }
  12. Object.setPrototypeOf(obj, proto);
  13. obj.foo();//20
  1. let proto = {
  2. y: 20,
  3. z: 40,
  4. bar:function() {
  5. console.log(this.y);
  6. }
  7. }
  8. let obj = {
  9. x: 10,
  10. foo() {
  11. // console.log(super.y);
  12. //对象的简写的写法才能生效;
  13. super.bar();
  14. }
  15. }
  16. Object.setPrototypeOf(obj, proto);
  17. obj.foo();//20

也没有问题,通过super调用方法

symbol

变量不重名可以通过let、const来定义,但对象里的属性不能通过let、const,可能会重名

symbol是一个原始值的类型

原始值类型的值
string number,boolean,null,undefined、symbol

引用值 Object、array、function

Symbol不是构造函数

Symbol不是构造函数Function,new 会报错,它是原始值,肯定不是构造函数function

  1. console.log(new Symbol());//TypeError: Symbol is not a constructor
  1. console.log(Symbol());//Symbol()

所有Symbol值都不一样

都不一样

  1. let s1=Symbol();
  2. let s2=Symbol();
  3. console.log(s1===s2);//false
  4. console.log(typeof s1);//symbol
  5. console.log(typeof(s1));//symbol

不能挂载属性

挂不上属性

  1. let s1=Symbol();
  2. s1.a=1;
  3. console.log(s1.a);//undefined

symbol是唯一的,那怎么找到它,通过传入参数,怎么区分不同的symbol的值,通过传参数
symbol本身值都是不一样的,传不传参数不影响,但想要找到,而不是赋予let xx=symbol,用xx,这时就需要参数了,参数就是数据,用参数区分,用数据查找

可以通过不同的参数,识别不同的symbol类型的值

  1. let s1=Symbol('foo');
  2. console.log(s1);//Symbol(foo)
  3. s1.a=1;
  4. console.log(s1.a);//undefined

image.png

会隐式转换成字符串

  1. var obj = {a: 1};
  2. let s1=Symbol(obj);
  3. console.log(Object.prototype.toString.call(obj));//[object Object]
  4. console.log(s1);//Symbol([object Object])
  1. var obj = {a: 1};
  2. // var s1=Symbol(null);///Symbol(null)
  3. var s1=Symbol(undefined);//Symbol() 没有不是Symbol(undefined)
  4. console.log(s1);

不能转换成数字

  1. let s1=Symbol(null);
  2. console.log(s1+1);//TypeError: Cannot convert a Symbol value to a number
  1. let s1=Symbol(null);
  2. console.log(Object.getPrototypeOf(s1));
  3. // console.log(s1+1);//TypeError: Cannot convert a Symbol value to a number
  4. // console.log(Number(s1))//TypeError: Cannot convert a Symbol value to a number
  5. console.log(String(s1));//Symbol(null)
  6. console.log(Boolean(s1));//true 只有Number不能转;

主要是以下三个方法

  1. let s1=Symbol(null);
  2. console.log(Object.getPrototypeOf(s1));

image.png

tostring方法

这个东西不太难,但知识点有点散,视频中是总结的,需要、应该对着视频把知识难点,知识点都给列下来,视频是保证听懂的,保证理解的,看视频理解知识点,把理解的知识点做成笔记,看视频听懂,必须做笔记,把知识点列下来,记录

  1. let s1=Symbol(null);
  2. console.log(s1.toString());//Symbol(null)
  1. let s1=Symbol(null);
  2. console.log(!s1);//false
  3. console.log(s1+'');//TypeError: Cannot convert a Symbol value to a string
  4. /*不能通过隐式转换,可以显示转换
  5. * 唯一可以隐式转换的是取反!s1,不报错,其它都报错,隐式转换仅限于Boolean*/
  6. console.log(s1.toString());//Symbol(null)
  1. let name=Symbol();
  2. let person={};
  3. person.name='zhangsan';
  4. /*.name自动转换成字符串,就不能用,想用name变量需要[]*/
  5. console.log(person['name']);//zhangsan
  1. let name=Symbol();
  2. let person={};
  3. person[name]='zhangsan';
  4. console.log(person);//{ [Symbol()]: 'zhangsan' }
  1. let name=Symbol();
  2. let person={
  3. [name]:'zhangsan'
  4. };
  5. console.log(person);//{ [Symbol()]: 'zhangsan' }
  1. let name=Symbol();
  2. let person={};
  3. Object.defineProperty(person,name,{
  4. value:'zhangsan'
  5. })
  6. console.log(person[name])//
  7. console.log(person)//{}设置在原型上面了

[]与symbol

  1. let name=Symbol();
  2. let eat=Symbol();
  3. let person={
  4. [name]:'zhangsan',
  5. [eat](){
  6. console.log(this[name])
  7. }
  8. }
  9. person[eat]();//zhangsan

for、keyfor

symbol与构造函数

  1. console.log(Symbol);//ƒ Symbol() { [native code] }
  2. console.log(Symbol());//Symbol()
  3. /*Symbol比较奇怪,是构造函数,但是不能new,只能通过方法执行的方式来运行*/

这是顶层定义的,顶层是c++等,底层定义时就这样定义的
以后行不行不知道,现在不行

for

Symbo.for(key键名,标识符:类型字符串)
返回值与Symbol()一样返回Symbol类型的值

Symbol永远拿到的是不一样的字符串,独一无二symbol类型的值

  1. let s1=Symbol('foo');
  2. let s2=Symbol('foo');
  3. console.log(s1===s2);//false

如果就想拿到一样的值,该怎么办?

  1. /*s1的时候,找key值为foo的symbol存不存在,不存在,新建
  2. * s2时时候,找key值为foo的symbol存不存在,存在,找之前声明过的symbol值*/
  3. let s=Symbol('foo');
  4. let s1=Symbol.for('foo');
  5. let s2=Symbol.for('foo');
  6. console.log(s1===s2);//true

keyfor

Symbo.keyfor(Symbol1,Symbol类型的值:类型Symbol)
作用:查找Symbol是的键值,并返回
返回值:Symbol的键值:字符串

  1. let s=Symbol('foo');
  2. let s1=Symbol.for('foo');
  3. let s2=Symbol.for('foo');
  4. console.log(s1===s2);//true
  5. console.log(Symbol.keyFor(s1));//foo
  6. console.log(Symbol.keyFor(s1)===Symbol.keyFor(s2));//true
  7. console.log(Symbol.keyFor(s));//undefined
  8. /*s并没有传key值,不是Symbol.for方法创造出来的*/

不能遍历Symbol属性的值

  1. const obj={};
  2. let a=Symbol('a');
  3. let b=Symbol('b');
  4. obj[a]='hello';
  5. obj[b]='world';
  6. obj.c='1';
  7. for (let i in obj) {
  8. /*只打印c的值,不会打印三个属性
  9. * for in不能遍历 Symbol属性的对象;*/
  10. console.log(i);//c
  11. console.log(obj[i]);//1
  12. console.log('run')//run
  13. }
  1. const obj={};
  2. let a=Symbol('a');
  3. let b=Symbol('b');
  4. obj[a]='hello';
  5. obj[b]='world';
  6. obj.c='1';
  7. for (let i in obj) {
  8. /*只打印c的值,不会打印三个属性
  9. * for in不能遍历 Symbol属性的对象;*/
  10. console.log(i);//c
  11. console.log(obj[i]);//1
  12. console.log('run')//run
  13. }
  14. for (let i of obj) {//TypeError: obj is not iterable
  15. console.log(i);
  16. }
  1. const obj={};
  2. let a=Symbol('a');
  3. let b=Symbol('b');
  4. obj[a]='hello';
  5. obj[b]='world';
  6. obj.c='1';
  7. for (let i in obj) {
  8. /*只打印c的值,不会打印三个属性
  9. * for in不能遍历 Symbol属性的对象;*/
  10. console.log(i);//c
  11. console.log(obj[i]);//1
  12. console.log('run')//run
  13. }
  14. /*
  15. for (let i of obj) {//TypeError: obj is not iterable
  16. console.log(i);
  17. }*/
  18. var obj1={};
  19. Object.assign(obj1,obj);
  20. console.log(obj1);//{ c: '1', [Symbol(a)]: 'hello', [Symbol(b)]: 'world' }
  21. /*可以被assign合并,但还是不能遍历合并的obj1,就想遍历怎么办?*/

getOwnPropertySymbols

  1. var obj1={};
  2. Object.assign(obj1,obj);
  3. console.log(obj1);//{ c: '1', [Symbol(a)]: 'hello', [Symbol(b)]: 'world' }
  4. /*可以被assign合并,但还是不能遍历合并的obj1,就想遍历怎么办?*/
  5. const objectSymbols=Object.getOwnPropertySymbols(obj);
  6. /*只会遍历obj中Symbol属性的值*/
  7. console.log(objectSymbols);//[ Symbol(a), Symbol(b) ]
  1. const obj = {c: 1, d: 2};
  2. let a = Symbol('a');
  3. let b = Symbol('b');
  4. let _a = Symbol('_a');
  5. let _b = Symbol('_b');
  6. obj[a] = 'hello';
  7. obj[b] = 'world';
  8. Object.defineProperties(obj, {
  9. e: {
  10. value: 5,
  11. enumerable: true
  12. },
  13. f: {
  14. value: 6,
  15. enumerable: false
  16. },
  17. [_a]: {
  18. value: -1,
  19. enumerable: true
  20. },
  21. [_b]: {
  22. value: -2,
  23. enumerable: false
  24. }
  25. })
  26. let h = Symbol('h');
  27. let i = Symbol('i');
  28. let j = Symbol('j');
  29. const obj1 = {
  30. g: 7,
  31. [h]: 8
  32. }
  33. Object.defineProperties(obj1, {
  34. [i]: {
  35. value: 9,
  36. enumerable: true
  37. },
  38. [j]: {
  39. value: 10
  40. },
  41. k: {
  42. value: 11
  43. }
  44. })
  45. Object.setPrototypeOf(obj, obj1);
  46. console.log(obj);
  47. console.log('--------')
  48. for (let i in obj) {
  49. console.log(i);
  50. }
  51. console.log('--------')
  52. console.log(Object.keys(obj));
  53. console.log('--------')
  54. console.log(Object.getOwnPropertySymbols(obj));

image.png

解析

  1. const obj = {c: 1, d: 2};
  2. let a = Symbol('a');
  3. let b = Symbol('b');
  4. let _a = Symbol('_a');
  5. let _b = Symbol('_b');
  6. obj[a] = 'hello';
  7. obj[b] = 'world';
  8. Object.defineProperties(obj, {
  9. e: {
  10. value: 5,
  11. enumerable: true
  12. },
  13. f: {
  14. value: 6,
  15. enumerable: false
  16. },
  17. [_a]: {
  18. value: -1,
  19. enumerable: true
  20. },
  21. [_b]: {
  22. value: -2,
  23. enumerable: false
  24. }
  25. })
  26. let h = Symbol('h');
  27. let i = Symbol('i');
  28. let j = Symbol('j');
  29. const obj1 = {
  30. g: 7,
  31. [h]: 8
  32. }
  33. Object.defineProperties(obj1, {
  34. [i]: {
  35. value: 9,
  36. enumerable: true
  37. },
  38. [j]: {
  39. value: 10
  40. },
  41. k: {
  42. value: 11
  43. }
  44. })
  45. Object.setPrototypeOf(obj, obj1);
  46. console.log(obj);
  47. console.log('--------')
  48. /*for in遍历自身和继承的可枚举属性(不包含Symbol类型的值);*/
  49. for (let i in obj) {
  50. console.log(i);
  51. }
  52. console.log('--------')
  53. console.log(Object.keys(obj));
  54. /*遍历自身可枚举的属性,不包含Symbol类型的值,需要可以枚举
  55. * 不包含继承*/
  56. console.log('--------')
  57. console.log(Object.getOwnPropertySymbols(obj));
  58. /*遍历自身Symbol上面的值,不需要可枚举,不可枚举的,也可以遍历*/
  59. var obj3 = {};
  60. Object.assign(obj3, obj);
  61. /*遍历自身可枚举的,包含symbol类型值的*/
  62. console.log(obj3)
  63. JSON.stringify()
  64. /*遍历自身可枚举的,不包含symbol*/

image.png