以下是关于“细品 JavaScript 寻址、闭包、对象模型和相关问题”的详细攻略。
一、JavaScript 寻址
JavaScript 寻址是指在访问对象的属性或方法时,JavaScript 引擎会自动查找对象及其原型链,然后返回相应属性或方法的值或引用。具体实现方式有点类似于链表,会一层层向上查找直到找到目标属性或方法。
例如,我们可以创建一个对象 person
:
let person = {
name: 'Tom',
age: 20,
sayHi() { console.log(`Hi, my name is ${this.name}.`); }
};
如果我们想要访问 person
对象的 name
属性和 sayHi
方法,可以这样做:
console.log(person.name); // 输出 'Tom'
person.sayHi(); // 输出 'Hi, my name is Tom.'
这里的 person.name
和 person.sayHi()
就是通过寻址获取 person
对象的属性和方法。
二、JavaScript 闭包
闭包指的是在函数内部创建另一个函数,并且另一个函数可以访问到外部函数的变量、参数和内部函数,即使外部函数已经执行完毕、退出调用栈,内部函数依然可以使用外部函数的变量、参数和内部函数。闭包可以延长变量的生命周期,并可以使用作用域链来实现一些高级的编程技巧。
例如,我们可以创建一个函数 outerFn
,并在其中定义一个内部函数 innerFn
:
function outerFn() {
let name = 'Tom';
function innerFn() {
console.log(`My name is ${name}.`);
}
return innerFn;
}
let inner = outerFn();
inner(); // 输出 'Myname is Tom.'
这里的 inner
是外部函数 outerFn
返回的内部函数 innerFn
,而 innerFn
可以访问到 outerFn
中的 name
变量,因为 innerFn
形成了一个闭包,保留了 name
变量的引用。
三、JavaScript 对象模型
JavaScript 对象模型(Object Model)指的是 JavaScript 的对象和其原型链的结构。在 JavaScript 中,所有的对象都是继承自 Object.prototype,而原型链是由 __proto__
属性连接起来的。当我们访问一个对象的属性或方法时,如果当前对象不存在该属性或方法,则会沿着原型链逐层查找,直到找到或者到达 Object.prototype。
例如,我们可以创建一个构造函数 Person
,并在 Person.prototype
上添加一个 sayHi
方法:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function() {
console.log(`Hi, my name is ${this.name}, I'm ${this.age} years old.`);
}
let person = new Person('Tom', 20);
person.sayHi(); // 输出 'Hi, my name is Tom, I'm 20 years old.'
这里的 person
对象继承了 Person.prototype
上的 sayHi
方法,而 Person.prototype
又继承了 Object.prototype 的方法。因此,person.sayHi()
在访问时会沿着原型链逐层查找,最终找到了 Person.prototype
上的 sayHi
方法。
示例一:使用 Object.defineProperty() 创建只读属性
在 JavaScript 中,我们可以使用 Object.defineProperty() 方法来创建只读属性。具体实现方式是使用 get 方法获取属性值,但没有 set 方法设置属性值,这样就实现了只读属性。
例如,我们可以创建一个对象 person
,并在其上创建一个只读属性 age
:
let person = {
name: 'Tom'
};
Object.defineProperty(person, 'age', {
get() { return 20; },
enumerable: true,
configurable: false
});
console.log(person.name); // 输出 'Tom'
console.log(person.age); // 输出 20
person.age = 25; // 不能修改只读属性
console.log(person.age); // 输出 20
这里的 Object.defineProperty()
创建了一个描述符对象,其中包括 get
方法获取属性值为 20
,而 enumerable
属性为 true
,表示能够被枚举,而 configurable
属性为 false
,表示不能删除或修改该属性,实现了只读属性。
示例二:使用 IIFE 创建私有变量
在 JavaScript 中,我们可以使用 IIFE(Immediately Invoked Function Expression)来创建私有变量,即对外部不可访问的变量。
例如,我们可以创建一个模块 counter
,并在其内部使用 IIFE 创建一个私有变量 count
,其外部无法访问:
let counter = (function() {
let count = 0;
return {
increment() { count++; },
decrement() { count--; },
getCount() { return count; }
};
})();
counter.increment();
counter.increment();
counter.decrement();
console.log(counter.getCount()); // 输出 1
这里的 counter
模块内部使用了 IIFE 创建了一个私有变量 count
,而通过返回一个包含闭包内的三个方法的对象,对外暴露了对 count
的操作方法,实现了对私有变量的保护。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:细品javascript 寻址,闭包,对象模型和相关问题 - Python技术站