JavaScript中的原型(prototype)及其作用是什么?

avatar
作者
筋斗云
阅读量:0
原型(prototype)是JavaScript中实现继承和复用的重要机制,每个对象都有一个原型对象,通过原型链实现属性和方法的共享。

一、JavaScript 中的原型与原型链

原型对象的基本概念 在 JavaScript 中,每个对象都有一个内置属性 [[Prototype]](在某些实现中被访问为 __proto__),它指向另一个对象,这个对象就是该对象的原型(prototype),当访问对象的属性或方法时,如果该对象本身没有定义该属性或方法,JavaScript 引擎就会沿着原型链去寻找,直到找到为止,原型链是一种机制,它将对象串联起来,形成了一条查找路径。
prototype 属性的作用 每个 JavaScript 的函数都有一个特殊的属性 prototype,该属性指向一个对象,函数的所有实例都可以继承这个对象上的属性和方法,prototype 属性是 JavaScript 实现继承的基础。
function Person(name) { this.name = name; }
Person.prototype.sayHello = function() { console.log('Hello, my name is ' + this.name); };
const person1 = new Person('Alice');
person1.sayHello(); // 输出: Hello, my name is Alice
在这个例子中,sayHello 方法被添加到了 Person.prototype 上,person1 可以通过原型链访问这个方法。

原型链详解

原型链的结构 JavaScript 的对象之间通过原型链联系起来,当你访问对象的属性时,JavaScript 会首先检查对象本身是否有该属性,如果没有,它会顺着原型链逐级向上查找,直到找到该属性或到达 null(原型链的终点),这个查找过程的顺序就是原型链的结构。
console.log(person1.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true
在上述例子中,person1 的 __proto__ 指向 Person.prototype,而 Person.prototype 的 __proto__ 又指向 Object.prototype,Object.prototype.__proto__ 是 null,表明已经到达原型链的顶端。
原型链的层级 我们可以理解原型链为一个层级结构:
实例对象的 __proto__ 指向其构造函数的 prototype 对象。
构造函数的 prototype 对象的 __proto__ 通常指向 Object.prototype。
Object.prototype 是所有对象的顶层原型,它的 __proto__ 为 null。

构造函数与原型对象

构造函数与 prototype 每当你使用构造函数创建对象时,该对象会自动获得对构造函数 prototype 属性中方法和属性的访问权限,这意味着你可以通过 prototype 为对象实例添加共享的属性和方法,而无需每次创建新实例时都重新定义这些属性和方法。
function Dog(name) { this.name = name; }
Dog.prototype.bark = function() { console.log(this.name + ' is barking!'); }
const dog1 = new Dog('Buddy');
const dog2 = new Dog('Charlie');
dog1.bark(); // 输出: Buddy is barking!
dog2.bark(); // 输出: Charlie is barking!
在这个例子中,bark 方法只定义了一次,但 dog1 和 dog2 实例都可以通过原型链访问并使用该方法,这不仅节省了内存,还提高了代码的复用性。
共享 vs. 实例属性 需要注意的是,使用 prototype 定义的属性是共享的,而使用 this 定义的属性是实例独有的。
function Cat(name) { this.name = name; // 实例属性 }
Cat.prototype.type = 'feline'; // 原型属性
const cat1 = new Cat('Whiskers');
const cat2 = new Cat('Felix');
console.log(cat1.type); // 输出: feline
console.log(cat2.type); // 输出: feline
cat1.type = 'domestic';
console.log(cat1.type); // 输出: domestic (实例属性覆盖了原型属性)
console.log(cat2.type); // 输出: feline
在这个例子中,cat1 的 type 属性被修改成了实例属性,不再从原型链中获取该值,而 cat2 依然保持原型中的 feline 值。

四、使用Object.create() 创建对象

使用Object.create() 创建对象 除了使用构造函数,JavaScript 还提供了Object.create() 方法来创建对象。Object.create() 方法接受两个参数:一个原型对象和一个包含属性描述符的对象字面量,通过Object.create(),你可以创建一个新对象,其原型被设置为第一个参数指定的对象。
const obj = Object.create(null);
obj.prop = 'value';
console.log(obj.prop); // 输出: value
在这个例子中,我们使用Object.create(null) 创建了一个新对象,并将它的prop 属性设置为 'value',由于我们没有指定任何原型,所以这个对象没有任何内置的方法或属性。

五、ES6 中的class 与原型

JavaScript中的原型(prototype)及其作用是什么?

class 语法糖 ES6 引入了class 关键字作为语法糖,使得编写基于原型的继承更加直观和简洁,虽然class 看起来与传统的类继承相似,但本质上仍然是基于原型的继承。
class Animal { speak() { console.log('Animal speaks'); } }
class Dog extends Animal { bark() { console.log('Dog barks'); } }
const dog = new Dog();
dog.speak(); // 输出: Animal speaks
dog.bark(); // 输出: Dog barks
在这个例子中,我们定义了一个Animal 类和一个继承自AnimalDog 类,尽管使用了class 关键字,但实际上仍然是基于原型的继承。
class 继承 ES6 的class 语法糖允许我们使用extends 关键字来实现继承,子类可以继承父类的属性和方法,同时还可以添加自己的属性和方法。
class Animal { speak() { console.log('Animal speaks'); } }
class Dog extends Animal { bark() { console.log('Dog barks'); } }
const dog = new Dog();
dog.speak(); // 输出: Animal speaks
dog.bark(); // 输出: Dog barks
在这个例子中,我们定义了一个Animal 类和一个继承自AnimalDog 类,尽管使用了class 关键字,但实际上仍然是基于原型的继承。

JavaScript 是一门强大的编程语言,其独特的对象模型基于原型链而非传统的类继承,本文详细介绍了 JavaScript 中的原型对象 prototype,帮助你深入理解其原理及应用场景。

相关问题与解答

1、问题:在 JavaScript 中,什么是原型链?

解答:原型链是一种将对象串联起来的机制,形成了一条查找路径,当访问一个对象的属性或方法时,如果该对象本身没有定义该属性或方法,JavaScript 引擎会沿着原型链逐级向上查找,直到找到该属性或方法或到达原型链的终点(null),这种查找过程的顺序就是原型链的结构。

2、问题:如何使用Object.create() 方法创建一个新对象?

解答:Object.create() 方法接受两个参数:一个原型对象和一个包含属性描述符的对象字面量,通过Object.create(),你可以创建一个新对象,其原型被设置为第一个参数指定的对象。<br>const obj = Object.create(null);<br>obj.prop = 'value';<br>console.log(obj.prop); // 输出: value<br>在这个例子中,我们使用Object.create(null) 创建了一个新对象,并将它的prop 属性设置为 'value',由于我们没有指定任何原型,所以这个对象没有任何内置的方法或属性。

以上内容就是解答有关“javascript学习笔记(九)javascript中的原型(prototype)及原型”的详细内容了,我相信这篇文章可以为您解决一些疑惑,有任何问题欢迎留言反馈,谢谢阅读。

    广告一刻

    为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!