美文网首页程序员
JavaScript快速上手——基础篇

JavaScript快速上手——基础篇

作者: 越长越圆 | 来源:发表于2016-10-07 01:48 被阅读874次

    背景

    ECMAScript是JavaScript的官方命名。因为Java已经是一个商标(它的原始持有者是Sun,现在是Oracle),所以它不得不准备一个新的名字。如今,一些早期收过授权的公司,如Mozilla,是允许使用JavaScript这个名字的。使用JavaScript这个名字通常需要遵循以下几个规则

    • JavaScript指的是一种编程语言
    • ECMAScript是正这种语言规范的名字。因此,每当提到这种语言的版本时,就是

    指ECMAScript。JavaScript当前的版本是ECMAScript5,ECMAScript6正在发展中。JavaScript 借鉴了各自编程语言,如Java(语法,原始值和对象),Scheme、AWK(第一类函数),Self(原型继承)、Perl和Python(字符串、数组和正则表达)。ECMAScript3之前,JavaScript都没有异常处理,这也就是为什么它经常会自动转换值和静默失败的原因:它最初不能抛出异常。
    一方面JavaScript有些怪异和功能缺失(比如块作用域、模块、子类支持等)。另一方面,它有许多强大的特性可以弥补这些问题。在其他的语言里,我们学的是语言特性,而在JavaScript中,我们学习的确实模式。JavaScript支持函数式编程(高阶函数、内置的map和reduce等)和面向对象编程(对象、继承)的混合式编程

    --
    JavaScript有很多值,都是我们预期的编程语言的值:如布尔值、数字、字符串、数组等。在JavaScript中使用的值都有属性。每一个属性都有一个key(或者是name)和一个value。可以认为,属性就是一条记录的字段。通过点操作符就可以读取属性:
    value.prokey点操作能动态赋值

    var str='abc'
    str.length//3
    
    'abc'.length//3
    
    var obj={}
    obj.foo=123;
    document.write(obj.foo)//123,神奇在本事obj没有foo这个key 动态加入 还能
    
    取出
    'hello'.toUpperCase()//'HELLO'
    

    原始值和对象

    • 原始值包括布尔值、数字、字符串、null和undefined。
    • 其他的值都是对象。简单对象、数组、正则表达式等

    undefined

    • 未被初始化的变量为undefined
    var foo;
    foo;
    undefined
    
    • 丢失的参数也会是undefined
    function f(x) {return x}
    f()
    undefined
    
    • 访问不存在的属性,也会得到undefined
    var obj={};
    obj.foo
    undefined
    

    null 是没有对象。在用到对象的时候它表示空值(例如参数、对象链中的最后一个元素等)。
    检查undefined或null

    if(x===undefined||x===null){
    }
    //也可以利用undefined和null都被视为false来处理
    if(!x){
    }
    //false,0,NaN'‘ 都可被视为false
    

    typeof主要用于原始值 ,instanceof用于对象

    • undefined ->undefined
    • null -> object
    • 布尔值 ->boolean
    • 数字 ->number
    • 字符串 -> string
    • 函数 -> function
    • 所有其他的常规值 -> object
    • 引擎创建的值 ->JavaScript 引擎可以被允许去创建一些值,且typeof的结果可

    以返回任意字符串(可以与表中列出的结果都不一样)

    布尔值

    在JavaScript中任意值都能表示布尔值。一下值会解释为false

    • undefined,null
    • 布尔值:false
    • 数字:-0、NaN。
    • 字符串: ''
      其他值都能被当做true
    Boolean(undefined)//false
    Boolean(0)//false
    Boolean(3)//true
    Boolean({})//true
    Boolean([])//true
    

    运算逻辑符

    和java的运算逻辑返回结果不同,java在&& ||等情况返回是true 或者false,在js中返回是运算符的一个结果

    NaN&&'abc'
    NaN//在java中应该返回一个false
    123&&'abc'
    abc//因为&&是计算到最后一个
    'abc'||123
    'abc'
    ''||123
    123//也是计算到最后一个
    

    在数字中NaN 是一个错误值

    Number('xyz')
    NaN
    

    Infinity多数情况也是一个错误值,Intnity是比任何一个数都要大(NaN除外)。同样,-Infiinty比任何一个数都要小(NaN除外)。这使得这两个数常用来做默认值(比如,当你需要一个最小值和最大值的时候)。

    3/0
    Infinity
    Math.pow(2,1024)
    Infiity
    
    //在函数中可以做三位运算符
    myFunction(y>=0?y:-y)
    

    函数声明具有提升特性--它们的实体会被移动到作用域的开始处。这使得我们可以引用后面声明的函数

    function foo(){
       bar();
       function bar(){
       }
    }
    //以上是被允许的
    

    var声明也具有提升特性,但是通过它们执行的赋值确不具备这个特性

    function f(){
      bar();
      var bar=function(){
      }
    }
    //这是错误代码
    

    特殊变量arguments

    在JavaScript中,函数的所以参数都可以被自由调用,它会通过arguments变量来使参数可用。arguments看起来像个数组,单却不具备数组的方法

    function f(){
      return arguments;
    }
    var args=f('a','b','c')
    args.length//3
    args[0]//a
    

    如果参数太多或太少 通过toArray函数来处理,额外的参数被忽略(arguments除外),丢失的参数会得到undefined

    function(x,y){
      console.log(x,y);
      return toArray(arguments);
    }
    function toArray(arrayLikeObject){
       return Array.prototype.slice.call(arrayLikeObject);
    }
    
    

    严格模式

    严格模式,激活更多的警告以及使javaScript变得更加干净(非严格模式有时候被叫做“松散模式”)。要切换到严格模式,在JavaScript文件或者 “<\scrpit/>”标签第一行输入:
    'use strict';
    也可以在没一个函数中激活严格模式:

    function functionInstrictMode(){
      ’user strict';
    }
    

    变量在函数作用域里

    一个变量的作用域总是完整的函数(相当于当前快)。例如:

    function foo(){
       var x=-512;
       if(x<0){
         var temp=-x; 
       }
       console.log(temp);//512
    }
    //temp并不局限于在某一个作用域里,知道函数结束都存在
    

    所有函数变量都会被提升:声明会被移动到函数的开始处,而赋值则仍然会在原来的位置进行。
    闭包
    --
    每个函数都和它周围的变量保持着连接,哪怕它离开被创建时的作用域也是如此

      function createIncrementor(start){
             return function(){
                start++;
                return start;
             }
         }
         var inc =createIncrementor(5);
         console.log(inc());
         console.log(inc());
         console.log(inc());
        //结果是6,7,8函数从开始被创建,在创建结束即离开它的上下文环境,但他
    
    仍然保持着start的连接。,函数以及它锁连接的周围的环境作用域中的变量即为
    
    闭包,所以createIncrementor()的返回其实就是一个闭包
    

    IIFE模式:引入一个新的作用域

    有时希望引入一个新的作用域,但是防止一个变量成为一个全局变量。在javaScript中,不能通过块来做,必须使用函数。这种模式可以将函数当做类似块的方式来使用。这种模式成为IIFE模式

    (function(){//打开IIFE
    var temp=...;
    }());//关闭IIFE
    

    IIFE是一个在定义之后被立即调用的函数表达式。在函数内部,会有一个新的作用域,以防止tmp变成全局变量。
    闭包造成的无意共享闭包会持续地外部变量保持连接

    var result =[];
    for(var i=0;i<5;i++){
       result.push(function (){return i});
    }
    console.log(result[1]());//5
    console.log(result[3]());//5
    //返回的总是i的当前值,而非函数被创建时的值。
    

    通过IIFE来获取当前i的快照

       var result =[];
    for(var i=0;i<5;i++){
        (function(){
            var i2=i;
            result.push(function (){
                return i2;
            })
        }());
    
    }
    console.log(result[1]());
    console.log(result[3]());
    

    对象和构造函数

    JavaScript两种基础的面向对象机制:单一对象和构造对象

    'use strict';
    var jane={
       name:'Jane'.
       describe:function(){
          return 'Persion named'+this.name
       }
    }
    describe是方法的形式
    jane.name//get
    jane.name='John'//set
    jane.newProperty='abc'//动态添加属性
    
    使用in来检查属性是否存在
    'newProperty' in jane//true
    'foo' in jane//false
    
    如果读取不存在的属性会得到undefined 因此之前要检查下
    
    jane.newProparty!==undefined//true
    
    jane.foo!==undefined//false
    
    使用delete移除属性
    delete jane.newPropetty//true
    'newPropetty' in jane/false
    

    提取方法

    如果对方法进行提取,则会失去与对象的连接。就这个函数而言,它不在是一个方法,this的值也会是undefined(在严格模式下)

    'use strict';
    var jane={
       name:'Jane'.
       describe:function(){
          return 'Persion named'+this.name
       }
    }
    var func=jane.describe;//TypeError: Cannot read property 'name' of 
    
    undefined
    func()
    

    解决方法使用bind(),所以函数都支持,它会创建一个this总是指向指定的新函数:

    'use strict';
    var jane={
       name:'Jane'.
       describe:function(){
          return 'Persion named'+this.name
       }
    }
    var func=jane.describe.bind(jane);
    func()
    

    方法中函数

    所以函数都有特殊的this变量。如果在方法中嵌套函数,这可能不太副本,因为在嵌套函数内部不能访问方法中的this变量

    var jane={
       name: 'Jane',
       friends:['Tarzan','Cheeta'],
       logHitoFriends:function(){
         'use strict';
         this.friends.forEach(function(friend){
         //this is undefined here
          console.log(this.name+' says hi to'+friend);
         });
       }
    }
    jane.logHitoFriends();
    //rror: Cannot read property 'name' of undefined
    
    

    解决办法第一种

    logHitoFriends:function(){
     'use strict';
     var that=this;
     this.friends.forEach(function(friend){
         //this is undefined here
          console.log(that.name+' says hi to'+friend);
         });
    }
    

    第二种,利用forEach的第二个参数,可以给this指定一个值

    logHitoFriends:function(){
     'use strict';
     this.friends.forEach(function(friend){
         //this is undefined here
          console.log(that.name+' says hi to'+friend);
         },this);
    }
    

    参考:深入理解JavaScript

    个人博客http://blog.csdn.net/qq_22329521/article/details/52747029

    相关文章

      网友评论

        本文标题:JavaScript快速上手——基础篇

        本文链接:https://www.haomeiwen.com/subject/olkyyttx.html