函数名

  1. var f=function (){
  2. console.log(arguments.callee.name); // f 可以拿到匿名函数
  3. console.log(f.name); // f
  4. }
  5. /*
  6. es5会打印空“” 因为现在都是es6,所以看不到es5的情况
  7. */
  8. console.log(f.name);//f
  9. f();
  1. // console.log(new Function.name);//TypeError: Function.name is not a constructor
  2. console.log(new Function().name);//anonymous
  3. console.log((new Function).name);//anonymous
  1. function foo(){}
  2. console.log(foo.name);//foo
  3. console.log(foo.bind({}).name);//bound foo
  4. console.log(foo.call({}).name);
  5. //TypeError: Cannot read properties of undefined (reading 'name')

对象的扩展

  1. const foo="bar";
  2. const baz={foo};
  3. // const baz={foo:foo};
  4. console.log(baz);//{ foo: 'bar' }
  1. const foo="bar";
  2. const baz={foo};
  3. /*当属性名=变量名的时候可以简写
  4. * foo等价于
  5. * 属性名foo:变量名foo*/
  6. // const baz={foo:foo};
  7. console.log(baz);//{ foo: 'bar' }

image.png

  1. function foo(a,b){
  2. console.log({a,b});//{ a: 1, b: 2 }
  3. console.log({a:a*2,b:b*2});//{ a: 2, b: 4 }
  4. }
  5. foo(1,2);
  1. const person={
  2. age:'12',
  3. say(){
  4. console.log(this.age)
  5. }
  6. }
  7. person.say()//12
  1. /*function foo(a,b){
  2. console.log({a,b});//{ a: 1, b: 2 }
  3. console.log({a:a*2,b:b*2});//{ a: 2, b: 4 }
  4. }
  5. foo(1,2);*/
  6. function foo(a=1,b=2){
  7. return {a,b}
  8. }
  9. let foo=(a=1,b=2)=>{a,b};

root.js

  1. function foo() {
  2. console.log(1)
  3. }
  4. function bar() {
  5. console.log(2)
  6. }
  7. function baz() {
  8. console.log(3)
  9. }
  10. let a = 3;
  11. const obj = {
  12. a,
  13. foo,
  14. bar,
  15. baz
  16. }
  17. module.exports.obj=obj;
  18. console.log(obj);
  19. /*{
  20. a: 3,
  21. foo: [Function: foo],
  22. bar: [Function: bar],
  23. baz: [Function: baz]
  24. }*/

main.js引用

  1. const obj=require('./root').obj;
  2. console.log(obj);
  3. /*{
  4. a: 3,
  5. foo: [Function: foo],
  6. bar: [Function: bar],
  7. baz: [Function: baz]
  8. }
  9. {
  10. a: 3,
  11. foo: [Function: foo],
  12. bar: [Function: bar],
  13. baz: [Function: baz]
  14. }
  15. */
  1. // const obj=require('./root').obj;
  2. /*通过解构赋值从obj拿到属性*/
  3. // const {a:a,foo:foo,bar:bar,baz:baz}=require('./root').obj;
  4. const {a, foo, bar, baz} = require('./root').obj;
  5. console.log(a);//3
  6. foo();//1
  7. bar();//2
  8. baz();//3
  1. var arr = [1, 23, 23, 45, 5];
  2. /*属性会进行包装,把所有传入的值进行一个包装,变成字符串
  3. * 定义的属性都是字符串*/
  4. console.log(arr[1]);//23
  5. console.log(arr["1"]);//23
  1. const obj={
  2. /* class(){
  3. }*/
  4. /*在对象中定义class方法,也可以,不冲突,但不推荐这样做
  5. * 其实是把class变成字符串*/
  6. "class":function (){
  7. }
  8. }

字符串可以用方法来利用它们

  1. let obj={};
  2. obj.foo=true;
  3. console.log(obj);//{ foo: true }
  4. /*拼接属性,通过表达式让属性拼接,变量相加减都是可以的*/
  5. obj['f'+'o'+'o']=false;
  6. console.log(obj);//{ foo: false }

属性名都会通过一种方式把它处理成字符串

  1. let a='hello';
  2. let b='world';
  3. /*三句话都是给obj的helloworld属性赋值*/
  4. let obj={
  5. [a+b]:true,
  6. ['hello'+b]:123,
  7. ['hello'+'world']:undefined
  8. }
  9. console.log(obj);//{ helloworld: undefined }
  1. var myObject = {};
  2. /*直接把true变成字符串*/
  3. myObject[true] = 'foo';
  4. myObject[3] = 'bar';
  5. myObject[myObject] = 'baz';
  6. console.log(myObject);//{ '3': 'bar', true: 'foo', '[object Object]': 'baz' }
  7. console.log(myObject['true']);//foo
  8. console.log(myObject['3']);//bar
  9. console.log(myObject[myObject]);//baz
  10. /*myObject对象被Object.prototype.toString方法转换成/[object Object]字符串,注意有[],
  11. * 不是转换成myObject字符串*/
  12. console.log(myObject['myObject']);//undefined
  13. console.log(myObject['[object Object]']);//true
  14. console.log(Boolean.prototype.toString.call(true));//true
  15. console.log(Object.prototype.toString.call(myObject));//[object Object]
  1. const a = {a: 1};
  2. const b = {b: 2};
  3. const obj={
  4. [a]:'valueA',
  5. [b]:'valueB'
  6. }
  7. console.log(obj);//{ '[object Object]': 'valueB' }

es5之前js并没有提供一个直接检测属性特征的方法,比如检测一个属性是否是只读属性,是否可以遍历,这些属性在es5之前都没有

es5,属性描述符:

  1. let obj={a:2};
  2. console.log(Object.prototype);

image.png

  1. let obj={a:2};
  2. // console.log(Object.prototype);
  3. console.log(Object.getOwnPropertyDescriptor(obj,'a'));

image.png
configurable:(可配置的),通过defineProperty添加一个新的属性,或者修改一个已有属性
enumerable:(可枚举)
writable:(可写)
value:(值)

  1. let obj = {};
  2. Object.defineProperty(obj, 'a',{
  3. value :2,
  4. enumerable : true,
  5. writable : true,
  6. configurable : true
  7. })
  8. console.log(obj);//{a:2}
  1. let obj = {};
  2. Object.defineProperty(obj, 'a', {
  3. value: 2,
  4. enumerable: true,
  5. writable: true,
  6. configurable: true
  7. })
  8. console.log(obj);//{a:2}
  9. console.log(Object.getOwnPropertyDescriptor(obj, 'a'));

image.png

  1. let obj = {};
  2. Object.defineProperty(obj, 'a', {
  3. value: 2,
  4. enumerable: true,
  5. /*设置为false,不可以更改*/
  6. writable: false,
  7. configurable: true
  8. })
  9. obj.a=3;
  10. /*es6在这里采取静默失败的策略,silenty field,属性没有生效,没有报错。
  11. * 偷偷不执行这条语句*/
  12. console.log(obj.a);//2
  1. "use strict";
  2. let obj = {};
  3. Object.defineProperty(obj, 'a', {
  4. value: 2,
  5. enumerable: true,
  6. /*设置为false,不可以更改*/
  7. writable: false,
  8. configurable: true
  9. })
  10. obj.a=3;
  11. //Uncaught TypeError: Cannot assign to read only property 'a' of object '#<Object>'
  12. /*es6在这里采取静默失败的策略,silenty field,属性没有生效,没有报错。
  13. * 偷偷不执行这条语句
  14. * 用严格模式use strict会报错*/
  15. console.log(obj.a);
  1. // "use strict";
  2. let obj = {};
  3. Object.defineProperty(obj, 'a', {
  4. value: 2,
  5. enumerable: true,
  6. /*设置为false,不可以更改,但可以删除,严格模式下删除也不报错*/
  7. writable: false,
  8. configurable: true
  9. })
  10. console.log(obj);//{a: 2}
  11. delete obj.a;
  12. console.log(obj.a);//undefined
  13. console.log(obj);//{}
  1. // "use strict";
  2. let obj = {};
  3. Object.defineProperty(obj, 'a', {
  4. value: 2,
  5. enumerable: true,
  6. writable: true,
  7. /*configurable设置为false就不能删除了,configurable:false,不能删除;
  8. * 但可以修改,writable设置为true,可以修改,*/
  9. configurable: false
  10. })
  11. obj.a = 3;
  12. console.log(obj);//{a: 3}
  13. delete obj.a;
  14. console.log(obj.a);//3
  15. console.log(obj);//{a: 3}

getter,setter

get操作,put操作

  1. var obj={
  2. log:['example','test'],
  3. get latest(){
  4. if (this.log.length===0) {
  5. return undefined;
  6. }
  7. return this.log[this.log.length-1];
  8. }
  9. }
  10. console.log(obj.latest);//test
  11. /*通过get方式重写了当前的获取属性的默认方式,obj.latest不再是之前原本的obj.a的方式来执行的,
  12. * 它访问值的方式是通过get的方式来定义的*/
  1. var obj={
  2. log:['example','test'],
  3. get latest(){
  4. if (this.log.length===0) {
  5. return undefined;
  6. }
  7. return this.log[this.log.length-1];
  8. },
  9. latest1(){
  10. if (this.log.length===0) {
  11. return undefined;
  12. }
  13. return this.log[this.log.length-1];
  14. }
  15. }
  16. console.log(obj.latest);//test
  17. console.log(obj.latest1());//test
  18. /*通过get方式重写了当前的获取属性的默认方式,obj.latest不再是之前原本的obj.a的方式来执行的,
  19. * 它访问值的方式是通过get的方式来定义的*/
  1. var myObject = {
  2. get a() {
  3. return 2;
  4. }
  5. }
  6. Object.defineProperty(myObject, 'b', {
  7. get: function () {
  8. // return this.a (2);
  9. return this.a * 2;
  10. },
  11. enumerable: true,
  12. /* value:6,
  13. writable : true*/
  14. /*都会报错,因为get已经有值了,已经是赋值语句,就不能在下面再给值了
  15. * value、writeable这俩是不让用的,与get方式矛盾,起冲突
  16. * configuable、enumerable可以用*/
  17. })
  18. console.log(myObject.a);//2
  19. console.log(myObject.b);//4

image.png

  1. var language = {
  2. set current(name) {
  3. this.log.push(name);
  4. },
  5. log: []
  6. }
  7. language.current = 'EN';
  8. language.current = 'FA';
  9. console.log(language.log);//['EN', 'FA']
  10. console.log(language.current);//undefined
  11. console.log(language.current = 'TE');//TE
  12. console.log(language.current);//undefined
  13. console.log(language.log);//['EN', 'FA', 'TE']
  1. var language = {
  2. set current(name) {
  3. this.log.push(name);
  4. },
  5. current1(name) {
  6. this.log.push(name);
  7. },
  8. log: []
  9. }
  10. language.current = 'EN';
  11. language.current = 'FA';
  12. console.log(language.log);//['EN', 'FA']
  13. console.log(language.current);//undefined
  14. console.log(language.current = 'TE');//TE
  15. /* language.current = 'EN'不是之前的赋值语句了,而是执行set current函数=“FA”,
  16. * 就是current("FA")*/
  17. console.log(language.current);//undefined
  18. console.log(language.log);//['EN', 'FA', 'TE']
  1. var obj={
  2. get a(){
  3. return 2;
  4. }
  5. }
  6. obj.a=3;
  7. console.log(obj.a);//2
  8. /*并不能等于3,一般有get属性,也得需要set属性,要不只能取值不能赋值,没有意义
  9. * 一般get、set都是成对出现的*/
  1. var obj={
  2. get a(){
  3. return 2;
  4. },
  5. set a(val){
  6. // return this.a*2;//3
  7. return val*2;//3
  8. }
  9. }
  10. console.log(obj.a=3);//3
  11. console.log(obj.a);//2
  1. var obj={
  2. get a(){
  3. // return 2;
  4. return this._a;
  5. },
  6. set a(val){
  7. // return this.a*2;//3
  8. // return val*2;//3
  9. this._a=val*2;
  10. }
  11. }
  12. console.log(obj.a=3);//3
  13. console.log(obj.a);//6

这个是get、set比较基本的用法,这个之后去练习

getter、setter操作,覆盖了原本的[[Get]]、[[Put]]操作