携手共探原型奥秘,链锁之上的奇妙世界
2023-09-15 07:44:55
在编程的世界中,原型(Prototype)是一个关键概念,它相当于一个模具,用来生产实例对象。每个实例对象都有一个指向原型对象的指针,而原型对象又有一个指向构造函数的指针,如此一来就形成了一条原型链,最终指向null
。
原型链是JavaScript实现继承的方式。当一个函数被用作构造函数时,它会创建一个新的原型对象,该原型对象继承自其父类的原型对象。这样,子类的实例对象就可以访问父类的属性和方法。
作用域是JavaScript中另一个重要的概念。它决定了变量和函数的可见性范围。作用域链是一个由当前作用域及其所有父作用域组成的链条。当在当前作用域中查找变量或函数时,会沿着作用域链逐级向上查找,直到找到为止。
闭包是JavaScript中的一种特殊函数,它可以访问其创建时所在的作用域中的变量。闭包的创建方式是在函数内部定义另一个函数,而内函数引用了外函数中的变量。
原型、原型链、作用域和作用域链、闭包这些概念共同构成了JavaScript编程语言的核心。掌握这些概念对于理解JavaScript的运行机制至关重要。
现在,让我们通过一些实例来加深对这些概念的理解。
原型:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log("Hello, my name is " + this.name);
};
const person1 = new Person("John");
person1.sayHello(); // Hello, my name is John
在上面的示例中,Person
函数是一个构造函数,它创建了Person
类型的对象。Person.prototype
是一个原型对象,它包含了所有Person
类型对象的共有属性和方法。person1
是一个Person
类型的实例对象,它继承自Person.prototype
。当调用person1.sayHello()
方法时,JavaScript会在person1
对象中查找sayHello
方法,如果没有找到,就会沿着原型链向上查找,直到在Person.prototype
对象中找到sayHello
方法。
原型链:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log("Hello, my name is " + this.name);
};
function Employee(name, department) {
Person.call(this, name);
this.department = department;
}
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
const employee1 = new Employee("John", "Engineering");
employee1.sayHello(); // Hello, my name is John
在上面的示例中,Employee
函数是一个子类构造函数,它继承自Person
函数。Employee.prototype
是一个子类原型对象,它继承自Person.prototype
。employee1
是一个Employee
类型的实例对象,它继承自Employee.prototype
和Person.prototype
。当调用employee1.sayHello()
方法时,JavaScript会在employee1
对象中查找sayHello
方法,如果没有找到,就会沿着原型链向上查找,直到在Person.prototype
对象中找到sayHello
方法。
作用域:
function outer() {
const outerVariable = "I am an outer variable";
function inner() {
const innerVariable = "I am an inner variable";
console.log(outerVariable); // I am an outer variable
console.log(innerVariable); // I am an inner variable
}
inner();
}
outer();
在上面的示例中,outer
函数是一个外部函数,它创建了一个名为outerVariable
的变量。inner
函数是一个内部函数,它创建了一个名为innerVariable
的变量。inner
函数可以访问outer
函数中的变量,但outer
函数不能访问inner
函数中的变量。
作用域链:
function outer() {
const outerVariable = "I am an outer variable";
function inner() {
const innerVariable = "I am an inner variable";
console.log(outerVariable); // I am an outer variable
console.log(innerVariable); // I am an inner variable
}
function deeper() {
const deeperVariable = "I am a deeper variable";
console.log(outerVariable); // I am an outer variable
console.log(innerVariable); // I am an inner variable
console.log(deeperVariable); // I am a deeper variable
}
inner();
deeper();
}
outer();
在上面的示例中,deeper
函数是一个更深的内部函数。deeper
函数可以访问outer
函数中的变量和inner
函数中的变量,但outer
函数和inner
函数都不能访问deeper
函数中的变量。
闭包:
function outer() {
const outerVariable = "I am an outer variable";
function inner() {
const innerVariable = "I am an inner variable";
return function() {
console.log(outerVariable); // I am an outer variable
console.log(innerVariable); // I am an inner variable
};
}
return inner();
}
const closure = outer();
closure();
在上面的示例中,outer
函数返回了一个闭包函数。闭包函数可以访问outer
函数中的变量和inner
函数中的变量,即使outer
函数和inner
函数已经执行完毕。
原型、原型链、作用域、作用域链和闭包这些概念是JavaScript编程语言的核心。掌握这些概念对于理解JavaScript的运行机制至关重要。