function A() {}
function B(a) {this.a = a;}
function C(a) {
if (a) {
this.a = a;
}
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;
console.log(new A().a);
console.log(new B().a);
1,new A().a
首先 new A()中没有 a属性 那么依照当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中寻找原则去他的__proto__中查找 而他的__proto__指向的是他构造函数的prototype属性即 A.prototype.a所以 输出 1
2,new B().a
new B()对象的构造函数已经为它创建了一个a属性 这个a属性的值为传入的参数,但是此次没有为构造函数传入参数 所以最后输出为 undefined
3,new C(2).a
构造函数C判断了创建实例时有没有传入参数 如果传入 则a属性为传入的参数 如果没有参数则不创建,这里传入了2 所以最后输出2 如果这里没有传入参数 那么输出的就是对象实例原型链中的a属性的值 结果为1
Function.prototype.a = 'a';
Object.prototype.b = 'b';
function Person(){};
var p = new Person();
console.log('p.a: '+ p.a);
console.log('p.b: '+ p.b);
console.log('Person.a: '+ Person.a);
console.log('Person.b: '+ Person.b);
Person ->实例 ->p,p中没有属性a与b 所以沿着原型链向上查找
p.__proto__指向Person.prototype 没找到, 继续向上找
p.__proto__.__proto__即Person.prototype.__proto__ 此时 Person.prototype的构造函数是Object
Person.prototype.__proto__指向的就是Object.prototype
p.b输出为‘b’
p.a 在原型链中一直未找到 所以为undefined
Person为构造函数他是内置对象Function的实例对象,即 Person.__proto__为 Function.prototype
故Person.a 输出为"a"
而在Person实例与__proto__中都没有找到b属性 此时会沿着原型链继续向上查找
而Person.__proto__._proto_(即Function.prototype._proto_)为 Object.prototype
所以 Person.b 输出为"b"
引申
- 所有的引用类型(数组,对象,函数)都具有对象特性,即可自由扩展属性(除了null以外)
- 所有的引用类型(数组,对象,函数),都有一个__proto__属性,属性值是一个普通的对象 (隐式原型)
- 所有的函数,都有一个prototype属性,属性值也是一个普通的对象
- 所有的引用类型(数组,对象,函数),__proto__属性值值向他构造函数的prototype属性值
- 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中寻找
-
实例生成时,会在内存中产生一块新的堆内存,对实例的一般操作将不影响其他实例,因为在堆内存里占据不同空间,互不影响;
-
this的指向问题,常见的情况包含如下几种:
作为对象方法时,谁调用就指向谁
作为函数调用时,指向全局顶层变量window
作为构造函数调用时,即new操作符生成实例时,构造函数中的this指向实例
call和apply方法中,显示指定this的绑定为指定上下文
-
字面量的方式(也有资料将literal翻译为直接量,个人认为后一种翻译其实更直观更形象)进行对象和数组赋值(数组本质也是对象)时,都是引用,即在堆内存生成资源,在栈内存生成变量,然后变量指向资源的地址。
-
赋值语句对于原始值赋值和引用类型赋值时的细节区别.