函数名
var f=function (){
console.log(arguments.callee.name); // f 可以拿到匿名函数
console.log(f.name); // f
}
/*
es5会打印空“” 因为现在都是es6,所以看不到es5的情况
*/
console.log(f.name);//f
f();
// console.log(new Function.name);//TypeError: Function.name is not a constructor
console.log(new Function().name);//anonymous
console.log((new Function).name);//anonymous
function foo(){}
console.log(foo.name);//foo
console.log(foo.bind({}).name);//bound foo
console.log(foo.call({}).name);
//TypeError: Cannot read properties of undefined (reading 'name')
对象的扩展
const foo="bar";
const baz={foo};
// const baz={foo:foo};
console.log(baz);//{ foo: 'bar' }
const foo="bar";
const baz={foo};
/*当属性名=变量名的时候可以简写
* foo等价于
* 属性名foo:变量名foo*/
// const baz={foo:foo};
console.log(baz);//{ foo: 'bar' }
function foo(a,b){
console.log({a,b});//{ a: 1, b: 2 }
console.log({a:a*2,b:b*2});//{ a: 2, b: 4 }
}
foo(1,2);
const person={
age:'12',
say(){
console.log(this.age)
}
}
person.say()//12
/*function foo(a,b){
console.log({a,b});//{ a: 1, b: 2 }
console.log({a:a*2,b:b*2});//{ a: 2, b: 4 }
}
foo(1,2);*/
function foo(a=1,b=2){
return {a,b}
}
let foo=(a=1,b=2)=>{a,b};
root.js
function foo() {
console.log(1)
}
function bar() {
console.log(2)
}
function baz() {
console.log(3)
}
let a = 3;
const obj = {
a,
foo,
bar,
baz
}
module.exports.obj=obj;
console.log(obj);
/*{
a: 3,
foo: [Function: foo],
bar: [Function: bar],
baz: [Function: baz]
}*/
main.js引用
const obj=require('./root').obj;
console.log(obj);
/*{
a: 3,
foo: [Function: foo],
bar: [Function: bar],
baz: [Function: baz]
}
{
a: 3,
foo: [Function: foo],
bar: [Function: bar],
baz: [Function: baz]
}
*/
// const obj=require('./root').obj;
/*通过解构赋值从obj拿到属性*/
// const {a:a,foo:foo,bar:bar,baz:baz}=require('./root').obj;
const {a, foo, bar, baz} = require('./root').obj;
console.log(a);//3
foo();//1
bar();//2
baz();//3
var arr = [1, 23, 23, 45, 5];
/*属性会进行包装,把所有传入的值进行一个包装,变成字符串
* 定义的属性都是字符串*/
console.log(arr[1]);//23
console.log(arr["1"]);//23
const obj={
/* class(){
}*/
/*在对象中定义class方法,也可以,不冲突,但不推荐这样做
* 其实是把class变成字符串*/
"class":function (){
}
}
字符串可以用方法来利用它们
let obj={};
obj.foo=true;
console.log(obj);//{ foo: true }
/*拼接属性,通过表达式让属性拼接,变量相加减都是可以的*/
obj['f'+'o'+'o']=false;
console.log(obj);//{ foo: false }
属性名都会通过一种方式把它处理成字符串
let a='hello';
let b='world';
/*三句话都是给obj的helloworld属性赋值*/
let obj={
[a+b]:true,
['hello'+b]:123,
['hello'+'world']:undefined
}
console.log(obj);//{ helloworld: undefined }
var myObject = {};
/*直接把true变成字符串*/
myObject[true] = 'foo';
myObject[3] = 'bar';
myObject[myObject] = 'baz';
console.log(myObject);//{ '3': 'bar', true: 'foo', '[object Object]': 'baz' }
console.log(myObject['true']);//foo
console.log(myObject['3']);//bar
console.log(myObject[myObject]);//baz
/*myObject对象被Object.prototype.toString方法转换成/[object Object]字符串,注意有[],
* 不是转换成myObject字符串*/
console.log(myObject['myObject']);//undefined
console.log(myObject['[object Object]']);//true
console.log(Boolean.prototype.toString.call(true));//true
console.log(Object.prototype.toString.call(myObject));//[object Object]
const a = {a: 1};
const b = {b: 2};
const obj={
[a]:'valueA',
[b]:'valueB'
}
console.log(obj);//{ '[object Object]': 'valueB' }
es5之前js并没有提供一个直接检测属性特征的方法,比如检测一个属性是否是只读属性,是否可以遍历,这些属性在es5之前都没有
es5,属性描述符:
let obj={a:2};
console.log(Object.prototype);
let obj={a:2};
// console.log(Object.prototype);
console.log(Object.getOwnPropertyDescriptor(obj,'a'));
configurable:(可配置的),通过defineProperty添加一个新的属性,或者修改一个已有属性
enumerable:(可枚举)
writable:(可写)
value:(值)
let obj = {};
Object.defineProperty(obj, 'a',{
value :2,
enumerable : true,
writable : true,
configurable : true
})
console.log(obj);//{a:2}
let obj = {};
Object.defineProperty(obj, 'a', {
value: 2,
enumerable: true,
writable: true,
configurable: true
})
console.log(obj);//{a:2}
console.log(Object.getOwnPropertyDescriptor(obj, 'a'));
let obj = {};
Object.defineProperty(obj, 'a', {
value: 2,
enumerable: true,
/*设置为false,不可以更改*/
writable: false,
configurable: true
})
obj.a=3;
/*es6在这里采取静默失败的策略,silenty field,属性没有生效,没有报错。
* 偷偷不执行这条语句*/
console.log(obj.a);//2
"use strict";
let obj = {};
Object.defineProperty(obj, 'a', {
value: 2,
enumerable: true,
/*设置为false,不可以更改*/
writable: false,
configurable: true
})
obj.a=3;
//Uncaught TypeError: Cannot assign to read only property 'a' of object '#<Object>'
/*es6在这里采取静默失败的策略,silenty field,属性没有生效,没有报错。
* 偷偷不执行这条语句
* 用严格模式use strict会报错*/
console.log(obj.a);
// "use strict";
let obj = {};
Object.defineProperty(obj, 'a', {
value: 2,
enumerable: true,
/*设置为false,不可以更改,但可以删除,严格模式下删除也不报错*/
writable: false,
configurable: true
})
console.log(obj);//{a: 2}
delete obj.a;
console.log(obj.a);//undefined
console.log(obj);//{}
// "use strict";
let obj = {};
Object.defineProperty(obj, 'a', {
value: 2,
enumerable: true,
writable: true,
/*configurable设置为false就不能删除了,configurable:false,不能删除;
* 但可以修改,writable设置为true,可以修改,*/
configurable: false
})
obj.a = 3;
console.log(obj);//{a: 3}
delete obj.a;
console.log(obj.a);//3
console.log(obj);//{a: 3}
getter,setter
get操作,put操作
var obj={
log:['example','test'],
get latest(){
if (this.log.length===0) {
return undefined;
}
return this.log[this.log.length-1];
}
}
console.log(obj.latest);//test
/*通过get方式重写了当前的获取属性的默认方式,obj.latest不再是之前原本的obj.a的方式来执行的,
* 它访问值的方式是通过get的方式来定义的*/
var obj={
log:['example','test'],
get latest(){
if (this.log.length===0) {
return undefined;
}
return this.log[this.log.length-1];
},
latest1(){
if (this.log.length===0) {
return undefined;
}
return this.log[this.log.length-1];
}
}
console.log(obj.latest);//test
console.log(obj.latest1());//test
/*通过get方式重写了当前的获取属性的默认方式,obj.latest不再是之前原本的obj.a的方式来执行的,
* 它访问值的方式是通过get的方式来定义的*/
var myObject = {
get a() {
return 2;
}
}
Object.defineProperty(myObject, 'b', {
get: function () {
// return this.a (2);
return this.a * 2;
},
enumerable: true,
/* value:6,
writable : true*/
/*都会报错,因为get已经有值了,已经是赋值语句,就不能在下面再给值了
* value、writeable这俩是不让用的,与get方式矛盾,起冲突
* configuable、enumerable可以用*/
})
console.log(myObject.a);//2
console.log(myObject.b);//4
var language = {
set current(name) {
this.log.push(name);
},
log: []
}
language.current = 'EN';
language.current = 'FA';
console.log(language.log);//['EN', 'FA']
console.log(language.current);//undefined
console.log(language.current = 'TE');//TE
console.log(language.current);//undefined
console.log(language.log);//['EN', 'FA', 'TE']
var language = {
set current(name) {
this.log.push(name);
},
current1(name) {
this.log.push(name);
},
log: []
}
language.current = 'EN';
language.current = 'FA';
console.log(language.log);//['EN', 'FA']
console.log(language.current);//undefined
console.log(language.current = 'TE');//TE
/* language.current = 'EN'不是之前的赋值语句了,而是执行set current函数=“FA”,
* 就是current("FA")*/
console.log(language.current);//undefined
console.log(language.log);//['EN', 'FA', 'TE']
var obj={
get a(){
return 2;
}
}
obj.a=3;
console.log(obj.a);//2
/*并不能等于3,一般有get属性,也得需要set属性,要不只能取值不能赋值,没有意义
* 一般get、set都是成对出现的*/
var obj={
get a(){
return 2;
},
set a(val){
// return this.a*2;//3
return val*2;//3
}
}
console.log(obj.a=3);//3
console.log(obj.a);//2
var obj={
get a(){
// return 2;
return this._a;
},
set a(val){
// return this.a*2;//3
// return val*2;//3
this._a=val*2;
}
}
console.log(obj.a=3);//3
console.log(obj.a);//6
这个是get、set比较基本的用法,这个之后去练习
getter、setter操作,覆盖了原本的[[Get]]、[[Put]]操作