欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Javascript 高级 高级内容学习笔记 (1)

最编程 2024-04-06 21:43:23
...

近期学习回顾JS高阶部分,深刻理解Javascript

基础不牢地动山摇!!

原型&原型链

构造函数

说起原型和原型链,我们需要先引入一个概念--构造函数

function Person() {

}
var person = new Person();
person.name = 'aa';
console.log(person.name) //aa

在这里,Person就是一个构造函数,可对Person进行实例化,使用new来创建一个实例对象person。在这个person对象中新建一个name属性赋值为'a'。

prototype

每个函数都会有个prototype属性

function Person() {

}
// 虽然写在注释里,但是你要注意:
// prototype是函数才会有的属性
Person.prototype.name = 'a';

var person1 = new Person();
var person2 = new Person();

console.log(person1.name) // a
console.log(person2.name) // a

我们可以在Person的prototype属性上新增一个name并赋值,那么实例对象person1、person2都可以获取到这个name的值。

Person的这个prototype属性就是指向了一个对象,这个对象也正是我们调用了该构造函数创建出来的person实例的原型,也就是person1、person2的原型。什么是原型?可以理解成:每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。此时

Peron(构造函数) ----- propotype -----> Person.prototype (实例的原型)

Person.prototype 和 person实例的关系就得引出新的点__proto__

__proto__

每个javascript对象(除了null)都带有一个默认的隐藏属性__proto__,此时这个属性就是会指向上面所说的实例原型Person.prototype,即 person.__proto__ === Person.prototype

构造函数有prototypeperson对象有__proto__都可以指向这个所谓的原型,那原型如何指向构造函数Person和实例person呢?

constructor

原型指向实例倒是没有,因为一个构造函数可以生成多个实例,但是原型指向构造函数是有的:通过constructor,每个原型都有一个 constructor 属性指向关联的构造函数,即 Perosn === Person.prototype.constructor

function Person() {

}
var person = new Person();

console.log(person.constructor === Person); // true

当获取 person.constructor 时,其实 person 中并没有 constructor 属性,当不能读取到constructor 属性时,会从 person 的原型也就是 Person.prototype 中读取,正好原型中有该属性,所以person.constructor === Person.prototype.constructor

综上所述,我们可以得到

function Person() {

}

var person = new Person();

console.log(person.__proto__ == Person.prototype) // true

console.log(Person.prototype.constructor == Person) // true

console.log(Object.getPrototypeOf(person) === Person.prototype) // true

原型.png

原型链

原型的原型是什么?

原型对象就是通过 Object 构造函数生成的,结合之前所讲,实例的 __proto__ 指向构造函数的 prototype

此时Peron.prototype的__proto__属性是指向Object的prototype,而Object.prototype的__proto__为null。

这种一连串通过对象的__proto__属性指向原型对象的关系指向性结构就是原型链

image.png

词法作用域&动态作用域

作用域

作用域就是指程序代码中定义变量的区域。 作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。 JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。

静态作用域

因为 JavaScript 采用的是词法作用域,函数的作用域在函数定义的时候就决定了。

而与词法作用域相对的是动态作用域,函数的作用域是在函数调用的时候才决定的

var value = 1

function foo(){
    console.log(value);
}

function bar(){
    var value = 2
    foo();
}

bar(); //1

假设JavaScript采用静态作用域,让我们分析下执行过程:

执行 foo 函数,先从 foo 函数内部查找是否有局部变量 value,如果没有,就根据书写的位置,查找上面一层的代码,也就是 value 等于 1,所以结果会打印 1。

假设JavaScript采用动态作用域,让我们分析下执行过程:

执行 foo 函数,依然是从 foo 函数内部查找是否有局部变量 value。如果没有,就从调用函数的作用域,也就是 bar 函数内部查找 value 变量,所以结果会打印 2。

前面我们已经说了,JavaScript采用的是静态作用域,所以这个例子的结果是 1。

待更新

推荐阅读