JavaScript: The Good Parts
Chapter 1 Good Parts:
JavaScript is an important language because it is the language of the web browser.
The very good ideas include functions, loose typing, dynamic objects, and an expressive object literal notation. The bad ideas include a programming model based on global variables.
The Web has become an important platform for application development, and JavaScript is the only language that is found in all browsers.
Chapter 2 Grammar:
Javascript中的保留字,但是大部分却没在这个语言中使用。undefined,NaN,Infinity也应该算保留字。
abstract
boolean break byte
case catch char class const continue
debugger default delete do double
else enum export extends
false final finally float for function
goto
if implements import in instanceof int interface
long
native new null
package private protected public
return
short static super switch synchronized
this throw throws transient true try typeof
var volatile void
while with
Reserved Words
JavaScript has a single number type. Internally, it is represented as 64-bit floating point, the same as Java's double. 1 and 1.0 are the same value.
NaN is not equal to any value, including itself. You can detect NaN with the isNaN(number) function. JavaScript has a Math object that contains a set of methods that act on numbers. Math.floor(number) method can be used to convert a number into an integer.
All characters in JavaScript are 16 bits wide. "A" === "\u0041". Strings are immutable.
A block is a set of statements wrapped in curly braces. Unlike many other languages, blocks in JavaScript do not create a new scope, so variables should be defined at the top of the function, not in blocks.
Below are the falsy values:
false
null
undefined
The empty string ''
The number 0
The number NaN
Falsy values
for in loop enumerates the property names (or keys) of an object. When iterating an array, use for (i = 0; i < arr.length; i++) { }. It is usually necessary to test object.hasOwnProperty(variable) to determine whether the property name is truly a member of the object or was found instead on the prototype chain.
var arr = [1,2,3,4,5,6,7,8,9];
arr[12] = 34;
for (var i in arr) {
console.log(i + " - " + arr[i]);
} for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
For loop
The try statement executes a block and catches any exceptions that were thrown by the block. The catch clause defines a new variable that will receive the exception object.
The throw statement raises an exception. If the throw statement is in a try block, then control goes to the catch clause. Otherwise, the function invocation is abandoned, and control goes to the catch clause of the try in the calling function.
JavaScript does not allow a line end between the return and the expression.
Chapter 3 Objects:
The simple types of JavaScript are numbers, strings, booleans (true and false), null, and undefined. All other values are objects. In JavaScript, arrays, functions, regular expressions, and objects are 'objects'.
The || operator can be used to fill in default values:
var middle = stooge["middle-name"] || "none";
var status = flight.status || "unknown";
|| operator
Attempting to retrieve values from undefined will throw a TypeError exception. This can be guarded against with the && operator:
flight.equipment // undefined
flight.equipment.model // throw "TypeError"
flight.equipment && flight.equipment.model // undefined
&& operator
Objects are passed around by reference. They are never copied.
All objects created from object literals are linked to Object.prototype, an object that comes standard with JavaScript.
if (typeof Object.create !== 'function') {
Object.create = function (o) {
var F = function () { };
F.prototype = o;
return new F();
};
} var another_stooge = Object.create(stooge);
Prototype
If we add a new property to a prototype, that property will immediately be visible in all of the objects that are based on that prototype.
The hasOwnProperty method does not look at the prototype chain.
Global abatement => Use a global object to create a top-level structure or use closure for information hiding.
Chapter 4 Functions:
- The method invocation pattern
var myObject = {
value: 0,
increment: function (inc) {
this.value += typeof inc === 'number' ? inc : 1;
}
}; myObject.increment(1);
document.writeln(myObject.value); // myObject.increment(2);
document.writeln(myObject.value); //
Example
- The function invocation pattern
When a function is not the property of an object, then it is invoked as a function, this is bound to the global object.
var me = {name: "Dave",
value: 4,
getName: function() { return this.name; }
}; var add = function(a, b) { return a + b; };
me.double = function () {
var helper = function () {
console.log(this);
};
helper();
};
me.double();
console.log(me.value);
This is bound to global object
var me = {name: "Shuai",
value: 4,
getName: function() { return this.name; }
}; var add = function(a, b) { return a + b; };
me.double = function () {
var that = this;
var helper = function () {
that.value = add(that.value, that.value);
};
helper();
};
me.double();
console.log(me.value);
Use that to represent this
- The constructor invocation pattern
var Quo = function (string) {
this.status = string;
}; // Give all instances of Quo a public method Invocation
Quo.prototype.get_status = function () {
return this.status;
};
// Make an instance of Quo.
var myQuo = new Quo("confused");
console.log(myQuo.get_status( )); // confused for (var prop in myQuo) {
if (myQuo.hasOwnProperty(prop)) {
console.log(prop);
}
}
Example
- The apply invocation pattern
var add = function (a, b) {
return a + b;
}; var arr = [3,4,5];
var sum = add.apply(null, arr);
console.log(sum); var statusObject = { status: "A-OK"}; var Quo = function (string) {
this.status = string;
}; // Give all instances of Quo a public method Invocation
Quo.prototype.get_status = function () {
return this.status;
};
// statusObject does not inherit from Quo.prototype,
// but we can invoke the get_status method on
// statusObject even though statusObject does not have
// a get_status method.
var getStatus = Quo.prototype.get_status.apply(statusObject);
console.log(getStatus);
Apply
A function always returns a value.If the return value is not specified,then undefined is returned.
var add = function (a, b) {
if (typeof a !== 'number' || typeof b !== 'number') {
throw {
name: 'TypeError',
message: 'add needs numbers'
};
}
return a + b;
} try {
add("seven");
} catch (e) {
console.log(e.name + ": " + e.message);
}
Example of Try...Catch...
By augmenting Function.prototype, we can make a method available to all functions:
Function.prototype.method = function (name, func) {
if (!this.prototype[name]) {
this.prototype[name] = func;
return this;
}
} Number.method("integer", function() {
return Math[this < 0 ? "ceil" : "floor"](this);
}); console.log((-10 / 3).integer()); String.method('trim', function () {
return this.replace(/^\s+|\s+$/g, '');
});
console.log(" neat ".trim());
Augment
Notice the () on the last line. The function returns an object containing two methods, and those methods continue to enjoy the privilege of access to the value variable.
var myObject = (function () {
var value = 0; return {
increment: function (inc) {
value += typeof inc === 'number' ? inc : 1;
},
getValue: function () {
return value;
}
};
}());
private members
var quo = function (status) {
return {
get_status: function () {
return status;
}
};
}; var myQuo = quo("amazed");
console.log(myQuo.get_status());
Use function to define an object
The function has access to the context in which it was created. This is called closure.
var fade = function (node) {
var level = 1;
var step = function () {
var hex = level.toString(16);
node.style.backgroundColor = '#FFFF' + hex + hex;
if (level < 15) {
level += 1;
setTimeout(step, 100);
}
};
setTimeout(step, 100);
}; fade(document.body); <html>
<body>
<pre>
<script src="program.js"></script>
</pre>
</body>
</html>
Fade the html page
Avoid creating functions within a loop. It can be wasteful computationally, and it can cause confusion, as we saw with the bad example.
// BAD EXAMPLE
// Make a function that assigns event handler functions to an array of nodes the wrong way.
// When you click on a node, an alert box is supposed to display the ordinal of the node.
// But it always displays the number of nodes instead.
var add_the_handlers = function (nodes) {
var i;
for (i = 0; i < nodes.length; i += 1) {
nodes[i].onclick = function (e) {
alert(i);
};
}
}; // BETTER EXAMPLE
// Make a function that assigns event handler functions to an array of nodes.
// When you click on a node, an alert box will display the ordinal of the node. var add_the_handlers = function (nodes) {
var helper = function (i) {
return function (e) {
alert(i);
};
};
var i;
for (i = 0; i < nodes.length; i += 1) {
nodes[i].onclick = helper(i);
}
};
Function context
String.method('deentityify', function () {
// The entity table. It maps entity names to
// characters.
var entity = {
quot: '"',
lt: '<',
gt: '>'
};
// Return the deentityify method.
return function ( ) {
// This is the deentityify method. It calls the string
// replace method, looking for substrings that start
// with '&' and end with ';'. If the characters in
// between are in the entity table, then replace the
// entity with the character from the table. It uses
// a regular expression (Chapter 7).
return this.replace(/&([^&;]+);/g,
function (a, b) {
var r = entity[b];
return typeof r === 'string' ? r : a;
}
);
};
}());
console.log('<">'.deentityify( )); // <">
Create a Module
var serial_maker = function ( ) {
// Produce an object that produces unique strings. A
// unique string is made up of two parts: a prefix
// and a sequence number. The object comes with
// methods for setting the prefix and sequence
// number, and a gensym method that produces unique
// strings.
var prefix = '';
var seq = 0;
return {
set_prefix: function (p) {
prefix = String(p);
},
set_seq: function (s) {
seq = s;
},
gensym: function ( ) {
var result = prefix + seq;
seq += 1;
return result;
}
};
};
var seqer = serial_maker( );
seqer.set_prefix('Q');
seqer.set_seq(1000);
var unique = seqer.gensym( ); // unique is "Q1000"
Use module to write secure code
var memoizer = function (memo, formula) {
var recur = function (n) {
var result = memo[n];
if (typeof result !== 'number') {
result = formula(recur, n);
memo[n] = result;
}
return result;
};
return recur;
}; var fibonacci = memoizer([0, 1], function (recur, n) {
return recur(n - 1) + recur(n - 2);
}); var factorial = memoizer([1, 1], function (recur, n) {
return n * recur(n - 1);
}); console.log(fibonacci(5));
console.log(factorial(5));
Memoization
Chaper 5 Inheritance:
JavaScript is a prototypal language,which means that objects inherit directly from other objects.
Chapter 6 Arrays:
Instead, JavaScript provides an object that has some array-like characteristics. It converts array subscripts into strings that are used to make properties. It is significantly slower than a real array, but it can be more convenient to use. Retrieval and updating of properties work the same as with objects, except that there is a special trick with integer property names. Arrays have their own literal format.
numbers.push('go'); // numbers is ['zero', 'one', 'two', 'shi', 'go']
delete numbers[2]; // numbers is ['zero', 'one', undefined, 'shi', 'go']
numbers.splice(2, 1); // numbers is ['zero', 'one', 'shi', 'go'], not go quickly for large arrays
Operations on Array
Distinguish between arrays and objects
var is_array = function (value) {
return value && typeof value === 'object' && value.constructor === Array;
}; Unfortunately,it fails to identify arrays that were constructed in a different window or frame.If we want to accurately detect those foreign arrays,we have to work a little harder: var is_array2 = function (value) {
return Object.prototype.toString.apply(value) === '[object Array]';
}; var arr = ["Red", true];
console.log(is_array(arr));
console.log(is_array2(arr));
Determine whether it is an array
Chapter 7 Regular Expressions:
var parse_url = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/; var url = "http://www.ora.com:80/goodparts?q#fragment"; var result = parse_url.exec(url);
var names = ['url', 'scheme', 'slash', 'host', 'port', 'path', 'query', 'hash'];
var blanks = ' '; var i;
for (i = 0; i < names.length; i += 1) {
console.log(names[i] + ':' + blanks.substring(names[i].length), result[i]);
}
An example
Chapter 8 Methods:
array.concat(item...)
array.join(separator) //faster than using '+'
array.pop()
array.push(item...)
array.reverse()
array.shift()
array.slice(start, end)
array.sort(comparefn)
array.splice()
array.unshift(item...) number.toExponential(fractionDigits)
number.toFixed(fractionDigits)
number.toPrecision(precision)
number.toString(radix) object.hasOwnProperty(name) regexp.exec(string)
regexp.test(string) string.charAt(pos)
stirng.charCodeAt(pos)
string.concat(string...)
stirng.indexOf(searchString, position)
string.lastIndexOf(searchString, position)
string.localeCompare(that)
string.match(regexp)
string.replace(searchValue, replaceValue)
string.search(regexp)
string.slice(start, end)
string.split(separator, limit)
string.substring(start, end)
string.toLocaleLowerCase()
string.toLocaleUpperCase()
string.toLowerCase()
string.toUpperCase()
String.fromCharCode(char...)
Chapter 9 Style
Chapeter 10 Beautiful Features
APPENDIX
Awful Parts:
Global variables
Scope
A variable declared in a block is visible everywhere in the function containing the block.
Semicolon Insertion
...
Bad Parts
JSLint
Syntax Diagrams
JSON
JavaScript: The Good Parts的更多相关文章
- JavaScript: The Evil Parts - 1
最近在看JavaScript框架设计,在讲解类型判定的时候提到了一些“匪夷所思的情况”,不过没有明说都是什么时候会出现这些情况.自己玩儿了一下,写写随笔吧.不过可能除了我找到的,还有会其他时候会出现这 ...
- 读 《JavaScript: The Good Parts》 有感
提炼出一门语言或技术的 Good Parts, 使用该子集去构造健壮稳固的应用. 我们总是倾向于去学习和使用所有的语言特性,好像凡是新的,凡是提供了的, 就有必要去使用: 这本书告诉我们, 要有选择性 ...
- 我要成为前端工程师!给 JavaScript 新手的建议与学习资源整理
来源于:http://blog.miniasp.com/post/2016/02/02/JavaScript-novice-advice-and-learning-resources.aspx 今年有 ...
- Javascript的实例化与继承:请停止使用new关键字
本文同时也发表在我另一篇独立博客 <Javascript的实例化与继承:请停止使用new关键字>(管理员请注意!这两个都是我自己的原创博客!不要踢出首页!不是转载!已经误会三次了!) 标题 ...
- [javascript] 使用闭包编写模块
这是一篇[javascript the good parts]的读书笔记. 我们知道可以利用javascript 的prototype 特性为原始类型编写拓展模块.利用如下方法: Object.pro ...
- 推荐几本 Javascript 书籍
初级读物: <JavaScript高级程序设计>:一本非常完整的经典入门书籍,被誉为JavaScript圣经之一,详解的非常详细,最新版第三版已经发布了,建议购买. <J ...
- [译]JavaScript规范-葵花宝典
[译]JavaScript规范 译自:https://github.com/airbnb/javascript 类型 原始值: 相当于传值 string number boolean null und ...
- JavaScript闭包的底层运行机制
转自:http://blog.leapoahead.com/2015/09/15/js-closure/ 我研究JavaScript闭包(closure)已经有一段时间了.我之前只是学会了如何使用它们 ...
- 第十章:Javascript子集和扩展
本章讨论javascript的集和超集,其中子集的定义大部分处于安全考虑.只有使用这门语言的一个安全的子集编写脚本,才能让代码执行的更安全.更稳定.ECMScript3标准是1999年版本的,10年后 ...
随机推荐
- AR模型与数据平稳性之间的关系
作者:桂. 时间:2017-12-19 21:39:08 链接:http://www.cnblogs.com/xingshansi/p/8068021.html 前言 前几天碰到一个序列分析的问题, ...
- Linux系统和工具集
Linux系统和工具集 阿里源 http://mirrors.aliyun.com/ http://centos.ustc.edu.cn/ 第三方包管理器 不同的发行版使用不同的软件包管理器,Cent ...
- untiy 2d游戏平面直角坐标系的旋转应用
2d旋转的应用 1 :条件1 (已知) 创建一个平面直角坐标系 左上角为(0,0),能够把一个加入了UIPanel组件的物体(名字叫Father)移至UIRoot左上角 Y和Z轴都旋转180度.这样你 ...
- [na]计算机网络性能指标(延迟/吞吐量/RTT等)
参考 计算机网络性能指标 计算机网络性能指标 带宽.速率.延迟.吞吐量.丢包率(无线验收标准一般-75dbm,del<100ms,丢包率3%) 带宽x延迟 决定着路上的数据的多少. 速率: 连接 ...
- C语言:存取结构体成员的点运算符(.)和箭头运算符(->)的区别
转自:http://blog.csdn.net/taric_ma/article/details/7397362 一直以为这两个是没有什么区别的,可以相互替换,今天又翻了一下<C语言核心技术&g ...
- Viewpager 去掉两侧的光晕效果
方案1: viewPager.setOverScrollMode(viewPager.OVER_SCROLL_NEVER); 方案2:通过反射的办法,直接操作具体控件具体的控件 private voi ...
- Python | 一行命令生成动态二维码
当我看到别人的二维码都做的这么炫酷的时候,我心动了! 我也想要一个能够吸引眼球的二维码,今天就带大家一起用 Python 来做一个炫酷的二维码! 首先要安装工具 myqr: pip install m ...
- android studio - 右键没有“New C++ Class 选项” 或 “Cannot find declaration to go to”的问题
今天在android studio的cpp文件夹上右键,发现竟然没有了New C++ Class“的选项,如下图所示: 上图是正常情况. 下图是非正常情况. 解决方案 检查”File“-"S ...
- FFmpeg(14)-使用NDK、C++完成EGL,display, surface, context的配置和初始化
EGL 用它开发需要做哪些事情. DIsplay 与原生窗口建立链接.EGL在Android中可以用java调,也可以用C++调. EGLDisplay eglGetDisplay ...
- Market Guide for AIOps Platforms
AIOps platforms enhance IT operations through greater insights by combining big data, machine learni ...