了解这些js原理你将成为更好的developer
1.Number 类型
在js中只有一种数值类型,双精度的数字和小数位的数值的计算在js中是不准确的。
例如:0.1+0.2是无法和0.3相等的。但是整数型的1 + 2 === 3。
Number的数据类型继承自Number.prototype方法。可以在number类型上调用这些方法:
(123).toString(); //"123" (1.23).toFixed(1); //"1.2"
parseInt() ,parseFloat(), Number(),这些全局方法可以转换为Number类型。
parseInt("1") //1
parseInt("text") //NaN
parseFloat("1.234") //1.234
Number("1") //1
Number("1.234") //1.234
无效的计算操作符或者无效的转换在将不会抛出异常,但是会得到NaN(Not a Number),isNaN()方法可以用于检测Not a Number
+号可以用于计算或者字符串拼接:
1 + 1 //2 "1" + "1" //"11" 1 + "1" //"11"
String类型:
可以用双引号或者单引号来表示字符串。
字符串类型的方法继承自String.prototype,例如substring(), indexOf(), concat()
"text".substring(1,3) //"ex" "text".indexOf('x') //2 "text".concat(" end") //"text end"
字符串类型具有不可变特性,例如concat()不会修改原来的字符串,而是会返回一个新的字符串。
Boolean类型
布尔类型有两个值: true 和 false.
以下等同于false:
false, null, undefined, ''(空字符串),0, NaN.
所有其他的值包括所有的对象都是等同于true,看如下例子:
let text = ''; if(text) { console.log("This is true"); } else { console.log("This is false"); }
Object类型:
Object类型是key value键值对的集合,key是个string,value的值可以是原始数据类型,对象或者函数。
创建对象常用的方式是使用对象字面量语法:
let obj = { message : "A message", doSomething : function() {} }
我们可以再任何时候读取,新增,编辑,删除对象的属性。
let obj = {}; //创建对象
obj.message = "A message"; //新增属性
obj.message = "A new message"; //编辑属性
delete obj.message; //删除属性
如果你要让对象不可变可以使用Object.freeze()方法。
Object.keys() 返回对象自身的可枚举的所有属性。
原始类型VS对象
原始类型是不可变的,但是对象是可变的。
变量:
声明变量的方式有 var let const
let声明方式具有块作用域,通过const声明的变量不能再次声明。但是它的值是可变的。const冻结变量,Object.freeze()冻结对象。const声明具有块作用域。声明再函数之外的变量具有全局性。
Array类型:
数组元素可以通过下标来获取,索引会被转换为字符串,例如:
arr[1]===arr['1'];
还有一种就是称之为 array-like的类数组。
{ '0': 'A', '1': 'B', '2': 'C' }
如果你使用delete去删除数组元素的话这里有个坑。
let arr = ['A', 'B', 'C']; delete arr[1]; console.log(arr); // ['A', empty, 'C'] console.log(arr.length); // 3
使用splice()方法可以避免这个问题,但是它的性能是比较慢的。
js是不会抛出索引超出范围的异常,如果索引不存在会返回undefined.
使用数组的方法我们可以模拟出栈和队列的概念.
let stack = []; stack.push(1); // [1] stack.push(2); // [1, 2] let last = stack.pop(); // [1] console.log(last); // 2 let queue = []; queue.push(1); // [1] queue.push(2); // [1, 2] let first = queue.shift();//[2] console.log(first); // 1
函数:
函数是对象,可以赋值给变量,储存在对象和数组中。作为参数传递给另外个函数或者作为返回值。
有三种方式定义一个函数:
1.函数声明
2.函数表达式
3.箭头函数
函数声明:
1.使用function作为第一个关键字
2.必须有个函数名name
3.调用函数可以位于函数的定义之前,函数声明会自动提升到作用域的顶部。
函数表达式:
1.function不是第一个关键字
2.函数名(name)是可选的,可以是一个匿名函数或者一个具名函数。
3.可以立即执行(IIFE)
箭头函数:
箭头函数是创建匿名函数的语法糖。
箭头函数没有属于他自己的this和arguments
通过function关键字声明的函数,可以通过不同的方法调用它
1.doSomething(param)
2.theObject.doSomething(param)
3.new DoSomething()
4.doSomething.apply(xxxxx) doSomething.call(xxxx)
5. let doSomething = doSomething.bind(thisObject);
doSomething();
可以通过一个或者多个参数来调用函数,超出的参数将会被忽略,而少传递的参数将会赋值为undefined。
关于this:
this存在于函数的上下文。只有通过function关键字声明的函数才有this上下文。this的值取决于函数执行的环境。
关于return:
函数如果为声明return的情况下,默认会返回undefined。请注意如下示例
function getObject(){ return { } } getObject()
上面的示例中,函数将不会返回空对象。而是会返回undefined。(注意return和花括号再不同行上),为了避免这种情况需要如下改造这个函数:
function getObject(){ return { } }
动态类型:
js具备动态类型的特性,值有类型,变量则没有。类型可以再运行的时候进行更改。
function log(value){ console.log(value); } log(1); log("text"); log({message : "text"});
typeof操作符可以检测变量的类型。
let n = 1; typeof(n); //number let s = "text"; typeof(s); //string let fn = function() {}; typeof(fn); //function
单线程
javascript是单线程的,所以js无法再同一个时间同时运行两个函数。js运行时候包含事件队列,这个事件队列存储着需要处理的事件信息。他们不存在竞争关系,也不存在锁死情况。
异常处理
js有一套自己的异常处理机制,我们可以使用try/catch语法来捕获js中的异常。但是有时候js会静静的吞没错误。不会抛出任何的exception。以下示例,当修改被冻结(freezon)对象的时候,js将不会抛出错误。
let obj = Object.freeze({});
obj.message = "text";
再js中使用严格模式将会显示抛出这样静默错误。
原型链模式
Object.create(),构造器函数,class,将会通过原型链构建对象。
考虑下如下示例:
let service = { doSomething : function() {} } let specializedService = Object.create(service); console.log(specializedService.__proto__ === service); //true
通过Object.create()构建一个新对象specializedService. service对象赋值为此对象的prototype,这就意味着doSomething方法存在于specializedService的原型链上。同时specializedService的__proto__属性指向service。
让我们通过class构建一个类似的对象。
class Service { doSomething(){} } class SpecializedService extends Service { } let specializedService = new SpecializedService(); console.log(specializedService.__proto__ === SpecializedService.prototype);
函数式模式
再js中函数作为一等公民,因此这使得函数式编程可以运用在js中。再函数式编程中有个高阶函数的概念,以函数作为参数或者返回的为函数,或者两者都有的再函数式编程中成为高阶函数。关于高阶函数的更多用法和概念可以参考社区里的博客文章。
浙公网安备 33010602011771号