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()/定時器啥的 :)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容