@smilence
2020-02-28T05:55:22.000000Z
字数 4274
阅读 1269
JavaScript SDE-Foundations
Boolean, Number, String, null, undefined和Symbol是primitive types,也就是基本类型。用===或!==时,比较的是他们的value。注意,永远不要用==或!=来比较变量。
JavaScript的
Number不区分整数和小数,比如5/2的结果是2.5。
String的literal可以用单引号或者双引号,但一般惯用单引号
变量没有被赋值时,JavaScript会认为它的值为undefined。当engineer想给variable赋一个代表空的值时,用null.
valid变量名必须以alphabet letter,
_或者$开头。开头以外的字符可以用大多数字符,但不包括-。
// Variables can be declared without an initial valuevar foo;var bar = 42;
相比于var, const代表这个变量的value不会改变。如果这个变量初始值是个object,也就是说这个变量永远reference同一个object。
var firstName = 'James';var lastName = 'Yu';// 用斜引号代表变量填空的string literal`My name is ${firstName} ${lastName}.` // "My name is James Yu"'My name is ${firstName} ${lastName}.' // "My name is ${firstName} ${lastName}."
function foo() {...}
var func = function() { // 这里就算给function起名也是无效的...}func();
通常都使用于一次性使用的情况,比如作为某个函数的参数,赋值给某个object的property等。 Brackets are optional when there's only one parameter / statement.
(x, y) => { return x + y; }(x, y) => x + y//(x) => { return x * 2; } // no implicit return for JSx => x * 2() => { console.log('warning'); }
if...else
if (x > y) {max = x} else if (x < y) {max = y} else {max = x}
var number = 1var array = []while (array.length < 10) {array.push(number);number += 1;}var i = 0while (i < 10) {// do something about array[i]}// 类似ruby中的 range (0..n).each, 不局限于处理arrayfor (var j = 0; j < 10; j++) {// do something about j}for (var j = 0; j < arr.length - 1; j++) {// do something about arr[j]}
// 访问obj的property name, 并不推荐用于arrayvar april = {age: 18,name: 'April',};for (prop in april) {console.log(obj[prop]);}
// 顺序访问array的property valuesvar arr = [1,2,3,4,5,6,7,8,9,10];for (ele of array) {console.log(ele);}
除了primitive types以外,其他的data都是object,所有的JavaScript function实际上也属于Function这个类别的object。而所有的object,都属于JavaScript当中的Object这个大类。
Object可以被认为是一些property的组合,property可以解释为"a variable attached to the object", 除了附属于object以外,property与一般的变量没有什么不同,比如每个property都由property name和property value组成。property value可以是任意类型,自然也可以是Function object。
e.g.function getAmountLimit(userId) {return location(userId) === 'US' ? 100 : 50}var obj = new Object();// 以下是一个object literal,也就是fixed value常量 ("literally"),类似于"abc"或者数字3.5var payment = {senderId: 100,receiverId: 101,amount: 30,amount_limit: getAmountLimit(senderId),}
对Object用===时,比较的是object的reference而不是object里的properties。(可以认为"objects are always represented as references", 所有object变量,存的都只是reference to the object)。所以一般不会用===去比较objects。
[1,2] === [1,2] // falsevar user = {name: 'Tom'}var owner = user// user和owner reference的是同一个object,所以改了owner的name相当于改了user的nameowner.name = 'James'user.name // 'James'
如果property name是valid变量名或者number,那么就可以省略引号。
var obj = {foo: 0, // valid, could be variable name'bar': 0, // string literals are always valid123: 0, // number literals are always valid1.5: 0, // ^foo-bar: 0, // invalid, would not be a valid variable name'foo-bar': 0, // string literals are always valid};
通常情况下property可以用objectName.propertyName来访问。如果property name不是一个valid变量名,或者是动态的,比如来自于一个string变量,那么就必须用[]. 注意和ruby的hash一样,JavaScript不能从property value来得到property name.
obj.0; // Error, not valid variable namevar field = 'test';obj.field // Error, field is a variable, not a literalobj[field];obj['example' + i]; // Dynamic, equivalent to a variableobj.prop = value;obj['prop'] = value;delete obj.prop // 删除某个property
// Nested property accessor,相比 [] 更清楚var obj = {foo: {bar: [42, 21]}};console.log(obj.foo.bar[0]);
arr.includes(ele) // ruby: arr.include?(ele)arr.slice(1,5) // ruby: arr[1...5]arr.join(' ') // ruby: arr.join(" ")arr.shift() // ruby: arr.shift()arr.unshift() // ruby: arr.unshift()arr.pop() // ruby: arr.pop()arr.push() // ruby: arr.push()
arr.forEach take function作为参数,但不使用function的结果。就像在ruby中arr.each会take block作为参数,但并不使用block的结果。
arr.forEach(function(ele, idx) {arr[idx] = ele * 2; // 返回值不会被使用,所以也不需要返回值});const copy = []; // copy永远reference这个array,但array的内容可以变化arr.forEach((ele) => {copy.push(ele);});arr.forEach(ele => {copy.push(ele);});
其他Iteration method和Ruby中的对应函数相似,会使用function的结果
const new_arr = arr.map(x => x*2); // ruby arr.map { |ele| ele*2 }const sum = arr.reduce((acc,ele) => acc + ele); // ruby arr.inject {|acc, ele| acc + ele}const sum = arr.reduce((acc,ele) => acc + ele, 0); // ruby arr.inject(0) {|acc, ele| acc + ele}const is_all_positive = arr.every(ele => ele > 0); // ruby arr.all? {|ele| ele > 0}const has_zero = arr.some(ele => ele === 0); // ruby arr.any? {|ele| ele == 0}