globalSayHello()
就是这样的一个方法。function globalSayHello() { console.log("hello"); } function Person() { var o = {}; o.sayHello = globalSayHello; return o; } var p1 = new Person(); var p2 = new Person(); p1.sayHello == p2.sayHello; // true
针对以上状况,能够将方法所有放到外面,好比,将sayHello()
单独定义到全局中,代码以下:javascript
function sayHello() {//TODO}
可是这么作会有以下安全隐患java
任意一个对象,都会默认链接到它的原型中数组
函数.prototype
引用,称其为函数的原型属性。强调一下是原型属性
function Person() {} var p = new Person(); /*p就是由Person函数做为构造函数建立出来的对象*/ /*在 Chrome 浏览器的 watch 中可使用以下方式查看结构*/ p._proto_ == Person.prototype // true
function Person(name) { this.name = name; } /* 在原型中定义了 printName() 方法 */ Person.prototype.printName = function () { console.log(this.name); }; var p = new Person("z4"); p.printName() /** * 构造函数 Person 中没有 printName() 这个方法 * 当 p 对象调用这个方法的时候,会先去构造方法中 * 查找,若是找不到,会去原型中查找。 */
从调试工具中能够看到,p
对象中是不存在 printName()
方法的,此方法是在 __proto__
对象中存在的浏览器
var f1 = new Foo(); var f2 = new Foo(); /* 若是 f1 中没有 sayHello 方法,就会去 Foo.prototype 中查找 */ f1.sayHello(); /* 若是 f2 中没有 sayGood 方法,就会去 Foo.prototype 中查找 */ f2.sayGood();
构造函数.prototype
构造函数.prototype 中
,那么全部的对象就能够共享了var arr = []; for(var i = 0; i < 4; i++) { arr.push({}); arr.push(function() {}) } console.log(arr[0] == arr[2]); //false console.log(arr[1] == arr[3]); //false /** * 分析: * 数组中每次新 push 的 {} 都是一个新的对象 * 因此 arr[0] == arr[2] 是 false * 同理,每次 push 的 function(){} 也是一个新的对象,因此也不相等 */ function createPerson() { var o = {}; o.sayHello = function () { console.log("hello"); }; return o; } var p1 = createPerson(); var p2 = createPerson(); console.log(p1 == p2); //false console.log(p1.sayHello == p2.sayHello); //false /** * 分析: * 每次执行 createPerson() 方法时 * o对象老是一个新的对象,因此 p1 == p2 是 false * 同理,sayHello 方法每次也是一个新的对象 */
如今考虑一个问题,这样建立出的对象是否很浪费资源,好比 sayHello
对象(方法也是一个对象),每次执行 createPerson()
方法都会建立一个都具备相同的功能,这样是一种资源的浪费。安全
function globalSayHello() { console.log("hello"); } function createPerson() { var o = {}; o.sayHello = globalSayHello; return o; } var o1 = createPerson(); var o2 = createPerson(); console.log(o1.sayHello == o2.sayHello); //true /** * 分析: * globalSayHello 赋值给 o.sayHello , 每次执行 createPerson() 方法时 * o.sayHello 指向的都是同一个对象,因此结果是 true,这样就解决了资源浪 * 费的问题,由于不管执行多少次 createPerson() 方法, o.sayHello 指向的 * 是同一个对象。 */
使用以上方式有个问题就是会定义不少的成员变量,每一个方法都是一个成员变量。这也是在重复对象
中提到的安全隐。可使用原型来解决这个问题。框架
function Person(name) { this.name = name; } /* 在原型中定义了 printName() 方法 */ Person.prototype.printName = function () { console.log(this.name); }; var p = new Person("王二麻"); var p1 = new Person("李四"); console.log(p.printName == p1.printName) //true /** * 不管建立多少个对象,printName 都只有一个,都是指向的同一个引用,因此 * 资源浪费的问题解决了,还有将方法定义在原型属性中,也减小了一个成员变 * 量。若是须要定义多个方法,均可以定义在原型属性中,也能够采用下面的方式 * 给原型属性赋值。 */ Person.prototype = { say: function () { return "hello"; }, hobby: function () { return "javascript"; } } var p2 = new Person("田七"); console.log(p2.say() + " " + p2.hobby()); //hello javascript
神秘对象针对构造函数称为原型属性
函数
神秘对象与构造函数所建立出来的对象也有必定关系工具
原型对象
对象继承自其原型性能
构造函数的原型属性
该对象的原型对象
构造函数建立的对象
与构造函数的原型属性表示的对象
是两个不一样
的对象