[[prototype]] 原型
JavaScript 中所有的对象都有一个内置属性[[prototype]], 是对其它对象的引用. 那么它默认情况下引用的是什么对象呢
该属性指向的其构造函数的原型 [[prototype]]通过_proto_来访问 或者通过 Object.getPrototypeOf(obj) 来访问
- <script type="text/javascript">
- var obj={a:"apple"};
- var num=new Number(10);
- var ifUp=true;
- console.log("obj.__proto__===Object.prototype:"+(obj.__proto__===Object.prototype));
- console.log("num.__proto__===Number.prototype:"+(num.__proto__===Number.prototype));
- console.log("ifUp.__proto__===Boolean.prototype:"+(ifUp.__proto__===Boolean.prototype));
- console.log("obj.__proto__===Object.getPrototypeOf():"+(obj.__proto__===Object.getPrototypeOf(obj)));
- console.log("num.__proto__===Number.getPrototypeOf:"+(num.__proto__===Object.getPrototypeOf(num)));
- console.log("ifUp.__proto__===Boolean.getPrototypeOf:"+(ifUp.__proto__===Object.getPrototypeOf(ifUp)));
- </script>
函数也是对象, 那么函数也有内置的 [[prototype]] 属性: 那么函数的 [[prototype]] 指向什么呢'<script type="text/javascript">
- function foo()
- {
- }
- console.log("foo._proto_:"+(foo.__proto__==Function.prototype));
- console.log("Object._proto_:"+(Object._proto_==Function.prototype));
- console.log("Number.__proto__ === Function.prototype"+(Number.__proto__ === Function.prototype)); // true
- console.log("Boolean.__proto__ === Function.prototype"+( Boolean.__proto__ === Function.prototype));// true
- console.log("Object.__proto__ === Function.prototype"+(Object.__proto__ === Function.prototype)); // true
- console.log("String.__proto__ === Function.prototype"+(String.__proto__ === Function.prototyp)); // true
- console.log("Function.__proto__ === Function.prototype"+(Function.__proto__ === Function.prototype)); // true
- console.log("Array.__proto__ === Function.prototype"+(Array.__proto__ === Function.prototype)); // true
- console.log("RegExp.__proto__ === Function.prototype"+(RegExp.__proto__ === Function.prototype)); // true
- console.log("Error.__proto__ === Function.prototype"+(Error.__proto__ === Function.prototype)); // true
- console.log("Date.__proto__ === Function.prototype"+ (Date.__proto__ === Function.prototype));
- </script>
执行结果如下:
可以看到所有构造器 / 函数的__proto__都指向 Function.prototype, 它是一个空函数(Empty function)
那么, 那 Function.prototype 的__proto__是谁呢?
通过上面的截图我们可以看到 Function.prototype._proto_指向的是 Object.prototype;
而: Object.prototype 的_proto_指向 null 既是 ojbect 位于 [[prototype]] 原型链的顶端.
原型链
由于_proto_是任何对象都有的属性, 而 JS 中万物皆对象, 所有会形成一条_proto_连起来的链条, 一直到头, 就是 Object.prototype._proto_指向 null
- <script type="text/javascript">
- var A = function(){};
- var a = new A();
- console.log(a.__proto__); //A {}(即构造器 function A 的原型对象)
- console.log(a.__proto__.__proto__); //Object {}(即构造器 function Object 的原型对象)
- console.log(a.__proto__.__proto__.__proto__); //null
- </script>
当查找对象属性的时候, 如果对象本身没有找到所需的属性, 就会继续访问对象的 [[prototype]] 链所以 JavaScript 中所有的对象都有可以调用 Object 的方法: 比如: toString()
如果需要查找的是互相不存在对象本事, 而在于原型链上会有三种情况产生
myObject.foo="bar"; //
1: 如果原型链存在 foo, 并在该属性没有标记为只读的, 那么会在 myObject 上添加一个 foo 属性, 屏蔽原型链上的 foo 属性
2: 如果原型链上存在 foo, 并在该属性被标记为只读的, 这条语句会被忽略, 不会发生屏蔽, 如果运行在严格模式下会报错
3: 如果原型链上存在 foo 并且标记为 setter , 会直接的调用这个属性, 不会再 myObject 上创建 foo 属性
使用 Object.defineProperty(): 可以把属性强制性添加到 myObject 上.
_proto_ 和 prototype
很多同学都搞不清楚它们之之间有什么区别
_proto_: 是所有对象 (包括函数) 都拥有的内置属性, 读取的内置 [[prototyope]] 内置属性
prototype: 是只有函数才有的
来源: http://www.bubuko.com/infodetail-3485074.html