为什么不直接在对象定义的时候同时声明method,有什么区别吗
今天刚好看到《高程》里面的这一部分内容,在第三版的147页,从这里开始详细介绍了原型相关的知识点。引用一下吧:
我们创建的每个函数都有一个prototype(原型)属性,这个属性时一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。如果按照字面意思来理解,那么prototype就是通过调用构造函数而创建的那个对象实例的原型对象。使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。换句话说,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。
一般来说,自己写的时候,实例都是要有属于自己的全部的属性的,所以很少看见有人单独使用原型模式。
function Person(name, gender) {
this.name = name;
this.gender = gender;
this.sayHello = function() {
console.log('Hello,I am', this.name, '. I\'m a', this.gender);
};
}
这样定义了一个构造函数,我们创建对象就可以使用这个构造函数作为模板来生成。不过以面向对象的思想来看,不难发现其中的一点问题:name和gender属性是每个实例都各不相同,作为一个自身的属性没有问题,而sayHello方法,每个实例对象应该都有,而且都一样,给每个实例对象一个全新的、完全不同(虽然代码内容一样,但JavaScript中每个sayHello的值都在内存中单独存在)的sayHello方法是没有必要的。
var zs = new Person('zhang san', 'male'),
xh = new Person('xiao hong', 'female');
zs.sayHello(); // Hello,I am zhang san . I'm a male
xh.sayHello(); // Hello,I am xiao hong . I'm a female
zs.sayHello === xh.sayHello; // false
上面代码中展示了zs.sayHell和xh.sayHello这两个作用相同,而且看起来代码内容也是完全一样的对象,实际是两个独立的,互不相关的对象。
面向对象思想中,是将公共的、抽象的属性和方法提取出来,作为一个基类,子类继承这个基类,从而继承到这些属性和方法。而JavaScript中则可以通过prototype属性来实现类似的作用。以下是上面代码的改进示例:
function Person(name, gender) {
this.name = name;
this.gender = gender;
}
Person.prototype.sayHello = function() {
console.log('Hello,I am', this.name, '. I\'m a', this.gender);
};
var zs = new Person('zhang san', 'male'),
xh = new Person('xiao hong', 'female');
zs.sayHello(); // Hello,I am zhang san . I'm a male
xh.sayHello(); // Hello,I am xiao hong . I'm a female
zs.sayHello === xh.sayHello; // true
应该能回答你的问题了,不过一般很少会xx.prototype={method:xx}
这么写的,而应该是xx.prototype.method=xxxx
。前者是直接替换了原型,后者是在原型上添加或者修改。
13 回答13k 阅读
7 回答2.2k 阅读
3 回答1.3k 阅读✓ 已解决
6 回答1.3k 阅读✓ 已解决
2 回答1.4k 阅读✓ 已解决
3 回答1.3k 阅读✓ 已解决
6 回答1.1k 阅读
没太看明白你的问题。
如果在构造函数内直接声明方法
这样实例化的多个对象之间的sayName不相等
但是如果将方法写在原型中,则多个实例的sayName都指向原型中,这样可以节约内存