JavaScript从基础到混合开发

本专题预计5节,旨在从基础到上手hybrid(主要是移动端react-native以及weex框架)开发。

** 几句题外话:前两节虽然比较基础,但都是js中比较重要的概念,面试过程中也应该会经常被问到。简单的概念我就不在此篇中赘述了。后三节内容则着重于实际开发踩到的坑。**

  • 数字 文本
  • null 和 undefined
  • 深复制与浅复制
  • 变量作用域

数字 文本

数字

有人会问数字有什么说的,好像确实是没有什么好说的,但我也硬总结了几个

1.大家要记住: ** js中的所有数字均用浮点数值标识 **,这意味着:他可以精确的表示分数,但这种二进制浮点数表示法并不能精确表示类似0.1这样简单的数字
看下这段代码:

console.log(0.3 - 0.2);//0.09999999999999998
console.log(0.2 - 0.1);//0.1

在开发中也会遇到类似情景,比如价格之类的计算,如遇到此类计算可以先将数值*10再进行操作。

2.记住几个常用的Math函数

  • Math.round(.6)//四舍五入
  • Math.ceil(.6)//向上取整1.0
  • Math.floor(.6)//向下取整0.0
  • Math.pow(2,23)//2的23次幂
  • Math.randow()//0-1.0的伪随机数
  • Math.max(x,y,z)//最大值
  • Math.min(x,y,z)//最小值 等等(剩下的自己看吧)。。

3.上溢(overflow)和下溢(underflow)

上溢:超过了js能表达数字上限,用 Infinity 和 -Infinity 标识

举个栗子

console.log(1/0);//Infinity
console.log(-1/0);//-Infinity

下溢:运算结果无限接近零,但超过了js能表示的值,这种情况就会返回『零』,当一个负数发生下溢是,返回『负零』

举个栗子

console.log(-1/Number.POSITIVE_INFINITY);//-0
console.log(Number.MIN_VALUE / 2);//0

思考:

console.log(Number.POSITIVE_INFINITY/Number.POSITIVE_INFINITY);//?
console.log(0/0);//?
console.log( 0 === -0);//?

4.NaN = not a number 经常会用isNaN来判断是否位数字

5.日期
js 提供了Date()对象,来表示日期和时间
var now = new Date();
var then = new Date([year],[month],[day],[hour],[minute],[second]);
then.getFullYear();//year
then.getmonth();//month 从0开始 剩下的自己看看吧

文本

1.操作字符串项目中经常使用的
var s = "hello, world";
s.charAt(0);//h
s.substring(1,4);//"ell" 取第二个到第四个字符
s.slilce(1,4);//同上
s.slice(-3);//"rld" 取最后三个字符
s.splite(", ");//["hello","world"] 分割字符串

2.正则匹配 [链接地址] (https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions)

null 和 undefined

我作为java开发者,只知道null,开发js后又来个undefined,让我一度很蒙逼啊 okay,下面这段话你读一读就懂了

null是一个特殊值,用来描述『空值』。对null执行typeOf,结果返回字符串 "object",也就是说 ** null可以看做特殊的对象值,含义是非对象 **

js中还有第二个值来表示值的空缺。用来定义更深层次的"空值",表明变量没有初始化。如果要查询对象属性或数组元素的值时返回undefined,则说明这个属性或元素不存在。

** 总之: undefined 标识系统级的,而 null 标识程序级,正常的,意料之中的值的空缺。 **

深复制和浅复制

怎么会出现深复制和浅复制这个概念呢?
首先,这种情况只会出现在对象的复制的
我们将对象称为引用类型,js中还有一个类型叫基本类型。对象的值都是引用,对象的比较均是引用的比较,当且仅当他们引用同一个对象是,他们才相等

再举个栗子:

var a = [];
var b = a;
b[0] = 1;
console.log(a[0]); //1
console.log(a === b);//true

你看对象b变了,a也就变了。结论就是将对象(或数组)赋值给一个变量,仅仅赋值的是引用值,对象本身并没有复制一次。如果你想得到一个对象或数组的副本,就要显式复制对象的每一个属性或数组的每个元素

再举个栗子:

var temp = ['a','b','c'];
var convert = [];
for(var i = 0 ; i < temp.length; i++){
    convert[i] = temp[i];
}

这样改变temp convert数组也不会受到影响

js中深复制实现的方法有很多,最简单的方法

var cloneObj = JSON.parse(JSON.stringify(obj));

上面这种方法好处是非常简单易用,但是坏处也显而易见,这会抛弃对象的constructor,也就是深复制之后,无论这个对象原本的构造函数是什么,在深复制之后都会变成Object。另外诸如RegExp对象是无法通过这种方式深复制的。

这边简单写了一个深复制,仅供参考学习


// 递归实现一个深拷贝
function deepClone(source){
   if(!source && typeof source !== 'object'){
     throw new Error('error arguments', 'shallowClone');
   }
   var targetObj = source.constructor === Array ? [] : {};
   for(var keys in source){
      if(source.hasOwnProperty(keys)){
         if(source[keys] && typeof source[keys] === 'object'){
           targetObj[keys] = source[keys].constructor === Array ? [] : {};
           targetObj[keys] = deepClone(source[keys]);
         }else{
           targetObj[keys] = source[keys];
         }
      } 
   }
   return targetObj;
}
// test example
var o1 = {
  arr: [1, 2, 3],
  obj: {
    key: 'value'
  },
  func: function(){
    return 1;
  }
};
var o3 = deepClone(o1);
console.log(o3 === o1); // => false
console.log(o3.obj === o1.obj); // => false
console.log(o2.func === o1.func); // => true


变量作用域

在js中,用var申明的变量实际上是有作用域的。就说点容易错的

** 没有被var修饰的变量,是全局变量 **

如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量:


function foo() {
    var x = 1;
    x = x + 1;
}

x = x + 2; // ReferenceError: x is not defined

由于JavaScript的函数可以嵌套(闭包),此时,内部函数可以访问外部函数定义的变量,但反之不可以

function foo() {
    var x = 1;
    function bar() {
        var y = x + 1; 
    }
    var z = y + 1;// ReferenceError: y is not defined
}

如果内部函数和外部函数的变量名重名,js会从内向外查找

function foo() {
    var x = 1;
    function bar() {
        var x = 'A';
        alert('x in bar() = ' + x); // 'A'
    }
    alert('x in foo() = ' + x); // 1
    bar();
}

变量提升
JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量提升到函数顶部:

function foo() {
    var x = 'Hello, ' + y;
    console.log(x); //hello,undefined
    var y = 'Bob';
}

相当于:

function foo() {
    var y;
    var x = 'Hello, ' + y;
    console.log(x); //hello,undefined
    y = 'Bob';
}

结语:下一节讲讲this/闭包/ bind() call() apply()/定时器啥的 :)

你可能感兴趣的:(JavaScript从基础到混合开发)