JavaScript 中的原生原型是 Object.prototype
对象的一部分。原型是对象之间继承特性的机制。
在 JavaScript 中,每个对象都包含一个原型属性。每个对象的原型包含与该对象相关的属性和方法。因此,这也被称为原生原型。
然而,你可以更新或向原生原型对象添加新的方法和属性,但是你不能删除已存在的任何方法或属性。
理解 JavaScript 原生原型的主要先决条件是了解 JavaScript 对象及其构造函数。
语法
你可以使用以下语法来访问对象的原生原型:
Object.prototype;
在上面的语法中,object
可以是任何 JavaScript 对象。
示例:访问数组的原型
当你在浏览器中执行以下代码时,它将在浏览器控制台中打印出数组的原型。同样的方式,你也可以检查其他对象的原型。
在控制台中,你可以看到原型对象包含了你可以与数组一起使用的那些方法。
<html>
<body>
<script>
console.log(Array.prototype);
</script>
<p>请在执行以上程序之前打开网页控制台。</p>
</body>
</html>
输出: 运行以上程序后,你会在网页控制台看到类似下面截图的结果:
JavaScript 数组原型
更新原生原型
你可以更新原生原型对象上现有的方法或属性,或者向原生原型对象添加一个新的方法或属性。
语法
你可以使用以下语法来更新或向原型对象添加新的属性或方法:
objName.prototype.name = value
在上面的语法中,objName
是你需要更新其原型的对象。
name
是方法或属性的名称。你可以给 name
赋予新的值或函数表达式。
示例:更新字符串对象原型上的 toLowerCase() 方法
字符串对象的原型包含了 toLowerCase()
方法。这里,我们将更新 toLowerCase()
方法。
更新后的 toLowerCase()
方法将以大写形式返回字符串。在输出中,你可以观察到字符串是以大写形式显示的。
通过这种方式,你可以更新对象内置方法的功能。
<html>
<body>
<p id="output">更新字符串 toLowerCase() 方法后: </p>
<script>
String.prototype.toLowerCase = function () {
return this.toUpperCase();
}
let str = "Hello World";
document.getElementById("output").innerHTML += str.toLowerCase();
</script>
</body>
</html>
输出: 更新字符串 toLowerCase() 方法后: HELLO WORLD
你不应该更新原生原型对象上的方法和属性。然而,你可以如下面示例所示添加新的方法。
示例:向原型对象添加新方法
你也可以向 Object
原型添加一个新方法。这里,我们在对象原型中添加了 firstCase()
方法。
firstCase()
方法会在转换字符串的第一个字符为大写后返回该字符串。
<html>
<body>
<p id="output">执行字符串 firstCase() 方法后: </p>
<script>
String.prototype.firstCase = function () {
return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase();
}
let str = "hello world";
document.getElementById("output").innerHTML += str.firstCase();
</script>
</body>
</html>
输出: 执行字符串 firstCase() 方法后: Hello world
向构造函数添加方法
无论何时使用构造函数定义一个对象,你都不能使用其实例向构造函数添加方法或属性。因此,你需要将方法添加到构造函数的原型上,这样所有对象的实例都可以访问它。
示例
在下面的示例中,Person()
是一个初始化对象属性的构造函数。
之后,我们在 person()
函数的原型上添加了 display()
方法。
然后,我们创建了 Person()
函数的两个实例,并使用了 display()
方法。因此,添加到对象构造函数原型上的方法和属性可以通过所有构造函数实例访问。
<html>
<body>
<p id="demo"> </p>
<script>
const output = document.getElementById("demo");
function Person(id, name) {
this.id = id;
this.name = name;
}
Person.prototype.display = function () {
output.innerHTML += this.id + ", " + this.name + "<br>";
}
const p1 = new Person(1, "James");
const p2 = new Person(2, "Nayan");
p1.display();
p2.display();
</script>
</body>
</html>
输出: 1, James 2, Nayan
所有对象的实例都会从其父原型继承属性和方法。
JavaScript 原型链
简单地说,原型存储了属性的默认值。如果对象构造函数及其原型包含相同的属性,则代码会覆盖原型属性的值。
示例
在下面的代码中,Person()
函数包含 name
属性。我们在函数的原型上添加了 name
和 age
属性。
我们使用 Person()
构造函数创建了 p1
对象。p1
对象的 name
属性值为 'Adam',因为 name
已经存在于构造函数中。age
属性的值为 20,这与原型中的 age
属性值相同。
<html>
<body>
<p id="output"> </p>
<script>
function Person(id, name) {
this.id = id;
this.name = name;
}
Person.prototype.name = "John";
Person.prototype.age = 20;
const p1 = new Person(1, "Adam");
document.getElementById("output").innerHTML =
"Id: " + p1.id + ", Name: " + p1.name + ", Age: " + p1.age;
</script>
</body>
</html>
输出: Id: 1, Name: Adam, Age: 20