hanyuxinting / Blog

记录点滴
1 stars 0 forks source link

JS权威指南读书笔记-4章 #1

Open hanyuxinting opened 7 years ago

hanyuxinting commented 7 years ago

1. 原始表达式-primary expression

表达式的原子级别。最小。常量/直接量、关键字、变量。 常量/直接量:1.23、'hello'、/pattern/----back to part3\10 关键字/js的一些保留字:true false null this 变量:i、sum、 undefined 当变量不存在时,表达式运算结果为undefined

2. 对象和数组的初始化表达式-对象直接量\数组直接量-新创建的对象和数组

不同于布尔直接量,非原始表达式,含有子表达式。 数组初始化表达式:[]、[1+2, 3+4]、[[1,2,3].[2,3,4]]、 [1,,,,,5] 这种中间空位会被填充为 undefined。

对象表达式:

3. 函数定义表达式-函数直接量-function

定义一个js函数。 以下代码中可以区别函数直接量和函数。 函数后不用加; 而函数直接量需要加;区分是声明变量结束。

4. 属性访问表达式-得到一个对象属性、或数组元素的值。(第六章)

. 运算和[]运算 先计算.[]运算符前的表达式,若为null或undefined,则抛出异常。so,经常用obj&&obj.x 这种语句判断。属性不存在,则返回undefined。 点运算符只适用要访问的属性名称是合法的标识符,且需要知道要访问的属性名。 用$.each可以遍历属性。 若属性名为保留字或包含空格和标点或是数字(数组而言),须使用方括号。 属性名是运算得出的值而不是固定值时,须用方括号。 对象属性:

数组属性:

5. 调用表达式-调用函数或方法。(第八章)

若函数使用return语句,则这个返回值为整个调用表达式的值。否则为undefined。 方法调用是针对一个对象里的方法而言。其实最终都是函数了~~(第九章) 普通函数调用,通常使用全局对象作为this的值,ES5严格模式下,this值为undefined。 了解严格模式 5.7.3

6. 对象创建表达式-创建一个对象并调用构造函数初始化新对象的属性。

new Object()/new Object
new Point(1,2)/new Point(1,2)

7. 运算符概述-关键字运算符、标点运算符。

delete instanceof

delete 删除属性

x = 42;        // 隐式声明的全局变量
var y = 43;    // 显式声明的全局变量
myobj = {
  h: 4,    
  k: 5
}    

// 隐式声明的全局变量可以被删除
delete x;       // 返回 true 

// 显式声明的全局变量不能被删除,该属性不可配置(not configurable)
delete y;       // 返回 false 

//内置对象的内置属性不能被删除
delete Math.PI; // 返回 false

//用户定义的属性可以被删除
delete myobj.h; // 返回 true 

// myobj 是全局对象的属性,而不是变量
//因此可以被删除
delete myobj;   // 返回 true

function f() {
  var z = 44;

  // delete doesn't affect local variable names
  delete z;     // returns false
}
// Numbers
typeof 37 === 'number';
typeof 3.14 === 'number';
typeof Math.LN2 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number'; // 尽管NaN是"Not-A-Number"的缩写
typeof Number(1) === 'number'; // 但不要使用这种形式!

// Strings
typeof "" === 'string';
typeof "bla" === 'string';
typeof (typeof 1) === 'string'; // typeof总是返回一个字符串
typeof String("abc") === 'string'; // 但不要使用这种形式!

// Booleans
typeof true === 'boolean';
typeof false === 'boolean';
typeof Boolean(true) === 'boolean'; // 但不要使用这种形式!

// Symbols
typeof Symbol() === 'symbol';
typeof Symbol('foo') === 'symbol';
typeof Symbol.iterator === 'symbol';

// Undefined
typeof undefined === 'undefined';
typeof declaredButUndefinedVariable === 'undefined';
typeof undeclaredVariable === 'undefined'; 

// Objects
typeof {a:1} === 'object';

// 使用Array.isArray 或者 Object.prototype.toString.call
// 区分数组,普通对象
typeof [1, 2, 4] === 'object';

typeof new Date() === 'object';

// 下面的容易令人迷惑,不要使用!
typeof new Boolean(true) === 'object';
typeof new Number(1) ==== 'object';
typeof new String("abc") === 'object';

// 函数
typeof function(){} === 'function';
typeof Math.sin === 'function';

// 定义构造函数
function C(){} 
function D(){} 

var o = new C();

// true,因为 Object.getPrototypeOf(o) === C.prototype
o instanceof C; 

// false,因为 D.prototype不在o的原型链上
o instanceof D; 

o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回true
C.prototype instanceof Object // true,同上

C.prototype = {};
var o2 = new C();

o2 instanceof C; // true

o instanceof C; // false,C.prototype指向了一个空对象,这个空对象不在o的原型链上.

D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true

// 数组
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
0 in trees        // 返回true
3 in trees        // 返回true
6 in trees        // 返回false
"bay" in trees    // 返回false (必须使用索引号,而不是数组元素的值)
"length" in trees // 返回true (length是一个数组属性)

// 内置对象
"PI" in Math          // 返回true

// 自定义对象
var mycar = {make: "Honda", model: "Accord", year: 1998};
"make" in mycar  // 返回true
"model" in mycar // 返回true

var color1 = new String("green");
"length" in color1 // 返回true
var color2 = "coral";
"length" in color2 // 报错(color2不是对象)

var mycar = {make: "Honda", model: "Accord", year: 1998};
delete mycar.make;
"make" in mycar;  // 返回false

var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
delete trees[3];
3 in trees; // 返回false

当你删除一个数组元素时,数组的 length 属性并不会变小。

8. 算术表达式

9.关系表达式

相等和不等运算符

== 可以允许类型转化。 === 则不允许类型转化。

1==='1'
false
1=='1'
true
null == null
true
null === null
true
undefined === undefined
true

null == undefined
true
null === undefined
false

true === true
true
null == null
true
false === false
true
NaN === NaN  // NaN 跟谁都不等,所以 x !== x ,
false
NaN == NaN
false
0 === -0
true
1 === -1
false

'北京' === '北京'
true
'\u2012' == '\u2012'
true
'北京' == '北京'
false
'北京'.localeCompare('北京')
0
'北京'.localeCompare('北京')
1

var s = new String('test'); s == 'test'
true
s === 'test'
false
s.valueOf() === s.toString()
true

'1' == true
true
'2' == true
false

NaN 跟谁都不等,所以 x !== x ,可以用来判断x是不是NaN~~

比较运算符

<
>
<=
>=

一般用于数字和字符串。

加号运算符和比较运算符的区别,加号以字符串优先,比较则以数字为优先。
1+2
3
1 + '2'
"12"
11>3
true
'11'>'3'
false
'11'>3
true
'one'>3 // 'one' -> NaN,NaN和任何比较都是false。
false

in 运算符

var point = {x: 1, y: 2};

point
Objectx: 1y: 2__proto__: Object__defineGetter__: __defineGetter__()__defineSetter__: __defineSetter__()__lookupGetter__: __lookupGetter__()__lookupSetter__: __lookupSetter__()constructor: Object()hasOwnProperty: hasOwnProperty()isPrototypeOf: isPrototypeOf()propertyIsEnumerable: propertyIsEnumerable()toLocaleString: toLocaleString()toString: toString()valueOf: valueOf()get __proto__: __proto__()set __proto__: __proto__()

'valueOf' in point
true
'__proto__' in point
true
'x' in point
true
'z' in point
false
var array = [4,5,6]; 4 in array
false
'4' in array
false

0 in array
true
'0' in array
true

instanceof 实例运算符

所有的对象都是Object的实例。 理解原型链~

var d = new String('test');
d instanceof String
true
d instanceof Date
false
d instanceof Object
true

10. 逻辑表达式

&&
||
!

以下等价:

if(a==b) do();
(a == b) && do();

11. 赋值表达式

= 给变量或属性赋值。 优先级很低的~

12. 表达式计算

eval

解释运行由 JS 源码组成的字符串,并返回值。 尽量不要用。

eval() 的问题:动态执行代码。 解释器不能提前优化。 当eval被赋值给其他变量时,调用该变量的方法很难优化。

eval() 传参字符串,并对该字符串当成JS代码进行编译(parse),编译成功后就执行该段代码。失败则抛出异常。

eval() 解析后的代码,如果有变量和eval外的代码相同,eval会使用该变量,甚至有可能改变该变量的值。 即,eval会改变它所在环境下的变量,如果很不幸这个eval在最顶层处调用,则会影响全局函数和全局变量。。

当其他代码来影响你的代码时,你的代码将会变得多么不可控~~~

// ##### 全局eval #####,不能修改局部变量和函数~
var g = eval; var x = 'gloval'; var y = 'global'; 
function f(){var x='local'; eval('x += "changed";'); return x;}
function gll(){var y='ll'; g('y += "changed";'); return y;}
console.log(f(), x);
localchanged gloval
console.log(gll(), y)
 ll globalchanged
console.log(y)
globalchanged
console.log(gll())
VM2113:1 ll
严格eval

私有上下文环境的局部eval~ 严格模式下,可以查询或更改局部变量,不能在局部作用域中定义新的变量或函数。 更像一个运算符~

但是,能不用就不要用了~~

13. 其他运算符

条件运算符~

?: 三目运算~

typeof运算符

两种写法~

x = null
typeof x
"object"
typeof(x)
"object"

void 运算符

一般用于 url中。

<a href="javascript:void(0);">我不跳转我就不跳转~</a>