1、ECMAScript中有两种属性:
数据属性和访问器属性;
数据属性(4个特性用于描述):
configurable:
能否通过delete删除属性而重新定义属性;
能否修改属性的特性;
能否把属性修改为访问器属性。
enumerable:
能否通过for-in循环返回属性。
writable:
能否修改属性的值。
value:
包含这个属性的数据值。
特点:
直接在对象上的属性(字面量形式或new Object()形式),默认值分别为:
configurable:true
enumerable:true
writable:true
value:undefined。
调用Object.defineProperty()方法创建一个新的属性时:
如果不指定(意味着可以指定),configurable、enumerable、writable的默认值均为false;
如果是修改已定义的属性的特性,则无此限制。
重点理解configurable:false:
可能是把configurable设置为false,也可能是调用...创建...新...属性时忘记设置configurable;
此时再调用Object.defineProperty()方法去修改除writable之外的特性,会导致错误:
注意是去修改,如果调用了方法,为某个特性重新设置一样的值,这是不会报错的
"除writable之外"没有得到验证?
访问器属性(4个特性):
get、set和 . = 的关系?
2、Uncaught RangeError: Maximum call stack size exceeded:栈溢出?
Object.defineProperty(o,"x",{
get:function(){ //?
return this.x;
},
set:function(arg){
this.x = arg;
this.y = arg + x;
}
});
3、对象通俗理解就是一组名值对,其中值可以是数据或函数。
4、自定义对象的toString()需要自己重写override。
5、创建对象:
工厂模式没有解决对象识别的问题;
构造函数模式:
将构造函数的作用域赋给新对象,因此this就指向了这个新对象:
函数的作用域和函数的this属性是什么关系?this大概与函数执行环境有关
函数如果有调用者,则this就指向调用者;
可以使用函数的call/apply方法为this指定指向对象;
对象也有作用域的概念;
当在全局作用域中调用一个函数时,this对象总是指向Global对象(浏览器中的window对象)。
构造函数的每个不同实例都有一个constructor属性,指向构造函数自己,原生函数同样;
区别构造函数与普通函数就是是否使用了new操作符调用:
如果不使用new来调用构造函数,属性和方法都被添加给window对象。
构造函数的问题是不同实例的同名函数是不相等的。
原型模式:
每个函数都有一个prototype(原型)属性,指向 通过调用构造函数创建的那个实例的 原型对象;
原型对象包含可以由特定类型的所有实例共享的属性和方法;
3个问题:
1.所有实例共享属性和方法?
共享方法就是函数在堆内存中的地址被赋给栈空间中的不同变量;
共享属性该如何理解?
2.封装问题?:
构造函数代码与prototype部分代码形式上有些分散。
3.对象的初始化问题?:
没有字面量的优势。
4.原型对象与构造函数是一一对应的吗?
构造函数的原型对象 实例的原型对象 本质上是同一个对象;
原型模式中,实例与构造函数没有直接的关系:
但是构造函数模式中,构造函数的每个不同实例都有一个constructor属性,指向构造函数,这在原型模式中也得到了验证?否:

总结:
1.构造函数有prototype属性,指向构造函数的原型对象;
2.原型对象有constructor属性,指向对应的构造函数;
3.函数的每个实例有[[Prototype]]属性(或_proto_),指向实例的原型对象;
4.实例的原型对象和函数的原型对象是同一个对象;
5.访问原型对象有两种方式:
a.通过构造函数:Person.prototype
b.通过函数实例:Object.getPrototypeOf(person)
6.规则不局限于构造函数,只要是创建一个函数;
7.当为对象添加一个属性时,这个属性就会屏蔽原型对象中保存的同名属性
in操作符作用于对象,当然也包括原型对象:
for/in枚举返回的属性均是String基本类型。
constructor属性的[[Enumerable]]特性默认是false,即是不可枚举的;
重写原型对象:
会切断构造函数与最初原型之间的双向链接关系;
已创建的实例不会直接链接到新的原型对象,实际上是通过最初原型与构造函数间接链接到新原型对象:
Object.getPrototypeOf(p8).constructor.prototype.name。
注意:当创建一个函数(显示定义)时,原型对象就会生成,而非使用new调用构造器时才生成。
6、变量名:
变量名是给编译器看的,编译器根据变量是局部还是全局分配内存地址或栈空间;
变量名在内存中不存在,操作时转换成地址数存放在寄存器中:
编译器会将合法的变量名放到一个叫“符号表”的一个表中,每个符号对应一个地址;
当你调用此变量时,就会根据此符号表找到对应的地址,然后进行操作。
5是一个常数,在程序编译时存放在代码的常量区存放着它的值(就是5):

浙公网安备 33010602011771号