关闭

[js] 变量 操作符 对象

209人阅读 评论(0) 收藏 举报
分类:

ES5

关键字和保留字

数据类型
基本数据类型: Undefined, Null, Boolean, Number, String
复杂数据类型: Object(由一组无须名值对组成)
基本数据类型是按值访问的(保存在栈内存中),引用类型的值是保存在堆内存中的对象。js不允许直接访问内存位置,因此在操作对象时实际操作的是对象的引用而非对象本身
在为对象添加属性时操作的是对象本身(或者说会通过引用访问到对象)
可以使用typeof来判断

var a;          typeof a; // undefined
var b = null;   typeof b; // object
var c = 'abc';  typeof c; // string
var d = true;   typeof d; // boolean
var e = 123;    typeof e; // number
var f = {};     typeof f; // object

undefined派生自null,因此null == undefined

Number
浮点数使用IEEE754,因此计算精度不如整数

0.1 + 0.2 // 0.30000000000000004
0.1 + 0.2 == 0.3 // false

无穷大(Infinity)和无穷小(-Infinity)无法参与运算

Number.NEGATIVE_INFINITY // -Infinity
Number.POSITIVE_INFINITY // Infinity
// 可以用isFinite判断是否是有穷数,是则返回true
isFinite(0) // true
isFinite(2e308) // false 

NaN(Not a Number)表示一个本来要返回数值但却未返回数值的情况
- 涉及NaN的任何操作都返回NaN
- NaN与包括本身在内的任何数值都不相等
- isNaN函数可用于判断,isNaN本身会做转换

1/0 // Infinity
-1/0 // -Infinity
0/0 // NaN
NaN*10 // NaN
NaN == NaN // false
isNaN(NaN) // true
isNaN('10') // false
isNaN('re') // true 

String

ES6扩展

Symbol
Symbol表示独一无二的值
Symbol通过Symbol函数生成

let s0 = Symbol();
// Symbol可接受字符串作为参数,用作Symbol实例的描述
let s1 = Symbol('a');
let s2 = Symbol('a');
// 相同参数的Symbol函数返回值不相等
s1 == s2; // false
// 
let s3 = new Symbol(); // Uncaught TypeError: Symbol is not a constructor

Symbol可转化为布尔值和显式转化为字符串,但无法转化为数值或隐式转化为字符串进行其他操作

var s = Symbol('a');

'what' + s; // Uncaught TypeError: Cannot convert a Symbol value to a string
`what ${s}`; // Uncaught TypeError: Cannot convert a Symbol value to a string
String(s); // 'Symbol(a)'
s.toString(); // 'Symbol(a)'
Boolean(s); // true
!!s; // true
if(s) {
    console.log('s');
} // 's'
Number(s); // Uncaught TypeError: Cannot convert a Symbol value to a number
s + 2; // Uncaught TypeError: Cannot convert a Symbol value to a number

Symbol作属性名
Symbol做属性名时不能通过点运算符赋取值

var s0 = Symbol();
var s1 = Symbol();

var a = {
    [s0]: 'wulala'
};

a.s0; // undefined
a[s0]; // 'wulala'

a[s1] = 'wulala';
a.s1; // undefined

Symbol作为属性名时是公有属性,但不会出现在for…in, for…of, Object.keys(), Object.getOwnPropertyNames(), JSON.stringify()中,可用Object.getOwnPropertySymbols获取

Symbol.for
Symbol.for()用于返回一个相同Symbol,若全局环境中有key已存在,就会直接返回
Symbol会生成一个登记信息,而Symbol()没有登记机制,因此每次生成的都是一个新的值

var s0 = Symbol('a');
var s1 = Symbol.for('a');
var s2 = Symbol.for('a');

s0 == s1; // false
s1 === s2; // true

Symbol.keyFor
用于返回登记机制,由于Symbol没有登记机制,因此返回时undefined

var s0 = Symbol('a');
var s1 = Symbol.for('a');

Symbol.keyFor(s0); // undefined
Symbol.keyFor(s1); // 'a'

Symbol.for登记的名字为全局环境,在所有的iframe和service worker中都可取到

mdn-Symbol

Object
Object类型是所有它的实例的基础
通过对象字面量定义对象不会调用Object构造函数

// 会修改全局Object函数,慎用
Object = function() {
    console.log('wulala');
}
var a = new Object(); // wulala
Var b = {} // 

ES6扩展

属性简介表示
对象的变量与函数均可简写

const st = 'aaa';
const b = {st};
b; // {st: "aaa"}
b.st = 'bbb';
st; // 'aaa'
b; // {st: "bbb"}

const c = {
  data() {
    return {
      // data
    }
  }
}

简写的属性名总是字符串,因此不会因为关键字导致语法解析报错
Generator函数前面要加*

属性名表达式
用表达式作为对象的属性名

const key = 'name';
const obj = {
  [key]: 'hudk',
  ['a' + 'ge']: 25,
  ['love who']: null,
  ['say some'] () {
    return 'hi girl.';
  }
};
obj[key]; // "hudk"
obj.name; // "hudk"
obj.age; // 25
obj['love who']; // null
obj['say some'](); // "hi girl."

属性名表达式不可与简介表示法同时使用
若属性名表达式为Object,则会转化为字符串[object Object]

Object.is
用于比较两个值是否相等
采用“Same-value equality”算法

Object.is('a', 'a'); // true
Object.is({}, {}); // false
Object.is(+0, -0); // false
+0 === -0; // true
Object.is(NaN, NaN); // true
NaN === NaN; // false

Object.assign
将源对象的所有可枚举属性复制到目标对象
后面的同名属性会覆盖前面的属性
返回值必须是对象,因此传入的首参无法转化为对象时会报错

const a = { o: 1 };
const b = {
  p: 2,
  q: 3,
}
const c = { q: 4 };
Object.assign(2); // Number {[[PrimitiveValue]]: 2}
Object.assign(a, b, c); // {o: 1, p: 2, q: 4}
a; // {o: 1, p: 2, q: 4}
Object.assign(null); // TypeError: Cannot convert undefined or null to object
Object.assign(undefined); // TypeError: Cannot convert undefined or null to object
Object.assign(a, null); // {o: 1, p: 2, q: 4}
Object.assign(a, undefined); // {o: 1, p: 2, q: 4}

Object.assign只拷贝自身属性,不拷贝继承属性和不可枚举属性

Object.assign({}, 1); // {}
Object.assign({}, true); // {}
Object.assign({}, [1, 2]); // { 0: 1, 1: 2 }

Object.assign是浅拷贝
可用来设置默认值(简单变量)

const DEFAULT = {
  host: 'hudk.test.com',
  port: 9000,
}
function getHTTP(option) {
  const Options = Object.assign({}, DEFAULT, option);
  // do sth.
}

属性遍历

var P = function () {
  this.name = '123';
}
var C = function () {
  this.age = '20';
}
C.prototype = new P();
var obj = new C();
Object.defineProperty(obj, 'unEnu', {
  enumerable: false,
  value: 'unEnum',
});

// for in返回自身及继承的可枚举属性
for (var i in obj) {
  console.log(i);
} // 'name' 'age'
// 返回自身的可枚举属性,不返回继承的可枚举属性
Object.keys(obj); // ['age']
// 包含不可枚举属性,不包含Symbol属性
Object.getOwnPropertyNames(obj); // ['age', 'unEnu']
// 包含不可枚举属性与Symbol属性
Reflect.ownKeys(per); // ['age', 'unEnu']

如果采用组合继承或ES6继承,则子类会在类内继承父类的所有属性,所以不再是集成属性,无论采用那种方式都可枚举
遍历顺序为:
1. 首先遍历所有属性名为数值的属性,按照数字排序。
2. 其次遍历所有属性名为字符串的属性,按照生成时间排序。
3. 最后遍历所有属性名为 Symbol 值的属性,按照生成时间排序。

proto
尽量不要使用_proto_,使用Object.setPrototypeOf,Object.getPrototypeOf,Object.Create代替

Array
如果设置索引超过数组长度,数组会自动增加到该索引加1的长度
数组的length属性可以修改,修改后新项为undefined
判断可使用Array.isArray()方法

sort方法
sort默认是对字符进行排序 15<5
- 可传入一个函数方法作为比较方法

function compare(val1, val2) {
  if(val1.num < val2.num) {
    return 1; // 交换
  } else if (val1.num > val2.num) {
    return -1; // 不交换
  } else {
    return 0; // 不交换
  }
}

var arr = [{num:3}, {num:2}, {num:3}, {num:0}, {num:9}];
arr.sort(compare);
arr; // [{num:9}, {num:3}, {num:3}, {num:2}, {num:0}]

concat, slice
两者都不会影响原来的数组而回返回一个新数组
两者都是浅复制

var a = [1, 2, 3];
var b = [5, 'a'];
a.concat('sdf', b, b); // [1, 2, 3, "sdf", 5, "a", 5, "a"]
a; // [1, 2, 3]
a.slice(1) // [2, 3]
a.slice(1, 2) // [2]
a.slice(-2, -1) // [2] 会加上数组长度
a.slice(2, 1) // []

splice
三个参数代表起始位置,删除项数(可为0),插入项

var a = [1, 2, 3];
a.splice(0, 1); // [1]
a; // [2, 3]
a.splice(0, 0, 'a', 'd'); // []
a; // ['a', 'd', 2, 3]
a.splice(2, 2, ['b', 'c']) // [2, 3]
a; // ['a', 'd', ['b', 'c']]

Function

RegExp

基本包装类型
Boolean, Number, String
在读取基本类型时后台会创建一个对应的基本包装类型的对象,调用方法是的步骤为:
1. 创建一个实例;
2. 在实例上调用方法;
3. 销毁实例。
使用new调用构造函数和调用转型函数结果不同

var a = 123;
var b = false;
var num = Number(a);
var obj = new Number(a);
var boo = Boolean(b);
var objB = new Boolean(b);

typeof num // number
typeof obj // object
boo || false // false
objB && true // true

单体内置对象
无需显示实例化
Global
Math

类型转换
转换为Boolean类型

String      非空字符    true     ''          false
Number      非零数     true      0,NaN       false
Objectnull     true     null        false
Undefined                       undefined   false

转换为Number类型
- 使用Number转化任意类型

String      
    只包含数字 转换为十进制
    包含浮点格式 转换为浮点
    包含十六进制 转换为对应十进制
    空 转换为0
    其他 转换为NaN
Boolean
    true 1
    false 0
Null
    0
Undefined
    NaN
Object
    调用valueOf方法,若结果为NaN,调用toString方法(测试发现无效仍然为NaN)
var a = '123.4';
var b = '0x1b';
var c = null;
var d;
var e = {};
e.valueOf = function () { return NaN; }
e.toString = function () { return '12'; }
Number(a); // 123.4
Number(b); // 27
Number(c); // 0
Number(d); // NaN
Number(e); // NaN
  • 使用parseInt转化字符串
    由于标准不同,建议带上第二个参数制定转换进制
var num = parseInt('AF', 16) // 175
  • 使用parseFloat转化字符串

转化为string类型
- toString
null与undefined没有toString方法
数字的toString可以带进制参数

// professional js for web developers p34
var num = 10;
num.toString(); // 10
num.toString(2); // 1010
num.toString(16); // a
  • String方法转化
    调用toString方法
    如果为null,返回null
    如果为undefined,返回undefined

操作符

var aa;
var bb = null;
aa + bb // NaN
aa + aa // NaN
bb + bb // 0

语句
with 设置代码作用域
严格模式下不能使用,且会导致性能下降(延长作用域)

var a = obj.func1();
var b = obj.func2();

with(obj) {
    a = func1();
    b = func2();
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:5048次
    • 积分:352
    • 等级:
    • 排名:千里之外
    • 原创:32篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类