【附录A—高级特性】《node.js开发指南》读书笔记

阅读: 评论:0

【附录A—高级特性】《node.js开发指南》读书笔记

【附录A—高级特性】《node.js开发指南》读书笔记

A.1 作用域

 作用域(scope)决定变量的可见范围和生命周期。

 

A1.1 函数作用域

在函数引用一个变量时,js会优先搜索当前作用域。如果没有找到则搜索上层作用域,直到顶层。

可是以下代码会带来困惑:

var scope = 'global';
var f = function () {console.log(scope); // 输出 undefinedvar scope = 'f';
}
f();

 因为在f函数内已经定义scope,但是他没有被初始化。所以输出undefined。

 

js使用静态作用域(词法作用域)。如下列代码,foo()仍然不会动态的使用a=3。

var a = 11;
function foo() {console.log(a);
}
function bar() {var a = 3;foo();
}bar(); // 2;

 

A.2 闭包

闭包(closure)是函数式编程中的概念。

 

A2.1 什么是闭包?

var generateClosure = function () {var count = 0;var get = function () {count++;return count;};return get;
};var counter = generateClosure();
console.log(counter()); // 输出 1
console.log(counter()); // 输出 2
console.log(counter()); // 输出 3

按照命令式编程思维的理解,count是函数内部的变量,他的生命周期只是在函数运行时。当函数从调用栈返回时,count变量申请的空间就被释放。

不过因为闭包特性,函数内部的get函数被一个外部变量counter时,就产生了一个闭包。

因为get访问了count,所以他没有被回收。

 

而且闭包实例之间是不共享内存的,比如:

var generateClosure = function () {var count = 0;var get = function () {count++;return count;};return get;
};
var counter1 = generateClosure();
var counter2 = generateClosure();
console.log(counter1()); // 输出 1
console.log(counter2()); // 输出 1
console.log(counter1()); // 输出 2
console.log(counter1()); // 输出 3
console.log(counter2()); // 输出 2

 

A.2.2 闭包的用途

2.实现私有成员

js没有私有属性,也就说每一个属性都是暴露给外部的,这样是不合理的。它会导致开发者能够直接函数修改属性值,破坏一致性。

通过闭包可以实现私有变量,还使用上面的代码作为演示:

var generateClosure = function () {var count = 0;var get = function () {count++;return count;};return get;
};
var counter = generateClosure();
console.log(counter()); // 输出 1
console.log(counter()); // 输出 2
console.log(counter()); // 输出 3

 其中只有特权函数get可以访问到count变量。私有属性便形成了。

 

A.3 对象

有别于其他的面向对象语言,js的对象是基于原型的。

 

A.3.1 创建和访问

js可以这样创建一个简单的对象:

var foo = {};foo.prop_1 = 'bar';
foo.prop_2 = false;foo.prop_3 = function(){return this.prop_1;
}console.log(foo.prop_3());

而且以下两种方式是等价的。

var foo1 = {};
var foo2 = new Object();

 

A.3.2 构造函数

 创建对象只是一次性的,我们需要多个对象,有属性,方法,并且能够初始化。

js提供了构造函数:

function User(name,uri){this.name = name;this.uri = uri;this.display = function(){console.log(this.name);}
}var someuser = new User('v','');

 

A.3.3 上下文属性

在js中,上下文对象就是this指针,即被函数调用的环境。

下列代码中,随着使用位置的不同,this也随之变化,所以输出也不尽相同。

var someuser = {name: 'byvoid',func: function () {console.log(this.name);}
};var foo = {name: 'foobar'
};
someuser.func(); // 输出 byvoidfoo.func = someuser.func;
foo.func(); // 输出 foobarname = 'global';
func = someuser.func;
func(); // 输出 global

 

A.3.4 原型

构造函数和对象区别:

1.构造函数内定义的属性继承方式与原型不同,子对象需要显式调用父对象才能继承构造函数内定义的属性。

2.构造函数内定义的任何属性,包括函数在内都会被重复创建,同一个构造函数产生的两个对象不共享实例。

但是原型链却是共享的,比如:

下列代码使用a2修改了a1原型链name的值。

function A(){this.setName = function(newName){A.prototype.name = newName;}
}A.prototype.name = "Sophie Dupont";let a1 = new A();
let a2 = new A();console.log(a1.name); //Sophie Dupont
a2.setName('Robert');
console.log(a1.name); //Robert

 3.构造函数内定义的函数有运行时闭包的开销,因为构造函数内的局部变量对其中定义的函数来说也是可见的。

 

 

原型链部分的内容介绍的比较粗浅,便不写入笔记了。

本文发布于:2024-02-02 16:58:02,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170686428045179.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:附录   读书笔记   特性   高级   指南
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23