zoukankan      html  css  js  c++  java
  • JavaScript笔记——基础知识(二)

    Function类型

    函数function不需要返回类型(不是没有返回值),参数也不需要指定类型,更为特殊的是函数竟然是个类,可以通过new出来

    var box= new Function('num1', 'num2' ,'return num1 + num2');

    这样的写法是完全正确的,但不推荐使用,因为会解析两次(第一次解析JavaScript代码,第二次解析参数)造成性能问题

    function可以当做参数使用

    很怪异,方法作为参数, 可以理解成把函数的引用作为参数)

    function box(sumFunction,num){            //将函数作为参数使用
        return sumFunction(num);
    }
    
    function sum(num){
        return num+10;                        //需要返回
    }
    
    alert(box(sum,10));

    函数内部属性

    在函数内部,有两个特殊的对象:argumentsthis

    arguments 是一个类数组对象,包 含着传入函数中的所有参数,主要用途是保存函数参数。但这个对象还有一个名叫 callee 的 属性,该属性是一个指针,指向拥有这个 arguments 对象的函数

    一个递归方法(可以使用arguments.callee方法代替调用本身)

    function box(num){
        if(num<=1){
            return 1;
        }else{
            //return num*box(num-1);
    return num*arguments.callee(num-1); } } alert(box(
    3));

    函数内部另一个特殊对象是 this,其行为与 Java 中的 this 大致相似。this 引用的是函数据以执行操作的对象,或者说函数调用语句所处的那个作用域,当在全局作用域中调用函数时,this 对象引用的就是 window

    var color='红色的';             //作用域
    alert(this.color);
    var box={
        color:'蓝色的',
        sayColor:function(){
            alert(this.color);
        }
    };
    box.sayColor();

    第一个this引用的是全局window,而第二个this引用的是box本身这个对象

    函数属性和方法

    JavaScript中的函数是对象,因此函数也有属性和方法。每个函数都包含两个属性: length prototype

    length 属性表示函数希望接收的命名参数的个数

    function box(name, age) {
    alert(name + age);
    }
    alert(box.length); //2

     prototype 属性,它是保存所有实例方法的真正所在,也就是原型。 prototype 下有两个方法:apply() call(),每个函数都包含这两个非继承而来的方法。这两个方法的用途都在特定的作用域中调用函数,实际上等于设置函数体内 this 对象的值

    apply()方法:

    function box(num1,num2){
        return num1+num2;
    }
    
    function sayBox(num1,num2){
        return box.apply(this,[num1,num2]);        //第二个参数是数组
    }
    
    function sayBox2(num1,num2){
        return box.apply(this,arguments);      //可以使用arguments替代参数列表
    }
    
    alert(sayBox2(10,10));

    call()方法:

    function box(num1,num2){
        return num1+num2;
    }
    
    function sayBox(num1,num2){
        return box.call(this,num1,num2);               //使用call方法传值不可以使用arguments
    }
    
    alert(sayBox(10,10));

    call()方法于 apply()方法相同,他们的区别仅仅在于接收参数的方式不同。对于 call()方法而言,第一个参数是作用域,没有变化,变化的只是参数传递的方式

    但事实上,传递参数并不是 apply()和 call()方法真正的用武之地;它们经常使用的地方是能够扩展函数赖以运行的作用域(对象冒充)

    var color='红色的';
    var box={
        color:'蓝色的'
    };
    function sayColor(){
        alert(this.color);
    }
    sayColor.call(this);                 //红色的
    sayColor.call(window);               //蓝色的
    sayColor.call(box);                  //apply和call方法的真正作用在于使对象和对象里的方法解耦合

    变量与作用域

    JavaScript 变量可能包含两种不同的数据类型的值:基本类型值和引用类型值。基本类型值指的是那些保存在栈内存中的简单数据段,即这种值完全保存在内存中的一个位置。 而引用类型值则是指那些保存在堆内存中的对象,意思是变量中保存的实际上只是一个指针,这个指针指向内存中的另一个位置,该位置保存对象(和Java的处理方式类似)

    变量

    对于变量类型和操作上和其他语言没有太大的差别,但需要注意基本类型和引用类型赋值操作的不同

    //基本类型
    var box='lee';                
    var box2=box;         //不同的,相互独立的两个空间
    box='alert';          //改变不会相互影响
    alert(box);
    alert(box2);
    
    //引用类型
    var box={
        name:'lee'
    };                
    var box2=box;         //不同的空间,相同的内容(同一个引用地址)
    box.name='alert';      //改变会相互影响
    alert(box.name);
    alert(box2.name);

    事实上Java中的类型也是这样操作的

    可以检测变量类型,使用typeof或instanceof

    var arr=[1,2,3];
    //alert(typeof arr);                   //typeof检测引用类型会出现 数组,对象,null都是object的问题,具体类型不知道
    alert(arr instanceof Array);          //使用instanceof检测引用类型
    
    
    var box='lz';
    //var box=new String('lz');
    alert(box instanceof String);             //但是instanceof检测基本类型会返回false.在这里如果String是new出来的,也会返回true 
    //alert(typeof box);                          //建议对基本类型的检测使用typeof ,对应用类型检测使用instanceof
    //Java也用instanceof检测类型,用法一致,但没有typeof

    作用域

    作用范围上其实与其他语言挺不同的,判断和循环语句的花括号竟然不能限定作用域

    if(true){                  //判断语句的花括号没办法限定其中值得作用域
        var i=10;
    }
    alert(i);                //10
    
    for(var i=0;i<10;i++){           //循环语句的花括号也没办法限定其中值得作用域
        var box='lz';
    }
    alert(i);                        //10
    alert(box);                      //lz
    
    function box(){            //只有function函数的花括号可以限定作用域
        var i=10;
    }
    alert(i);                 //报错

    还有就是this在全局的范围代表的window对象

    var color='红色的';             //作用域
    alert(this.color);
    var box={
        color:'蓝色的',
        sayColor:function(){
            alert(this.color);
        }
    };
    box.sayColor();
    alert(this.color);        //红色的   等同于alert(window.color); 

    传递参数

    JavaScript中所有函数的参数都是按值传递的,参数不会按引用传递,虽然变量有基本类型和引用类型之分,其实C++,java都是按值传递的,PHP是两种方式都有

    function box(num) { //按值传递,传递的参数是基本类型
    num += 10; //这里的 num 是局部变量,全局无效
    return num;
    }
    var num = 50;
    var result = box(num);
    alert(result); //60
    alert(num); //50

    以上的代码中,传递的参数是一个基本类型的值。而函数里的 num 是一个局部变 量,和外面的 num 没有任何联系

    容易混淆的是下面的代码

    function box(obj) { //按值传递,传递的参数是引用类型
    obj.name = 'lz';
    }
    var p = new Object();
    box(p);
    alert(p.name);            //lz

    结果改变了,这是因为我们按值传递一个地址的引用(可以这样理解),然而存在了不同空间,相同的内容(同一个引用地址),就会相互影响

    包装类

    为了便于操作基本类型值,JavaScript提供了 3 个特殊的引用类型:Boolean、Number 和 String。这些类型与其他引用类型相似,但同时也具有与各自的基本类型相应的特殊行为。 实际上,每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象, 从而能够调用一些方法来操作这些数据,所以才可以向下面一样操作:

    //var str='Mr.li';
    //alert(str.substring(2));
    alert('Mr.li'.substring(2));        //根据指定位置向后截取

    这三个包装类提供了丰富的方法和属性来操作它们对应的基本类型,这里不一一记录了

  • 相关阅读:
    Hibernate save, saveOrUpdate, persist, merge, update 区别
    Eclipse下maven使用嵌入式(Embedded)Neo4j创建Hello World项目
    Neo4j批量插入(Batch Insertion)
    嵌入式(Embedded)Neo4j数据库访问方法
    Neo4j 查询已经创建的索引与约束
    Neo4j 两种索引Legacy Index与Schema Index区别
    spring data jpa hibernate jpa 三者之间的关系
    maven web project打包为war包,目录结构的变化
    创建一个maven web project
    Linux下部署solrCloud
  • 原文地址:https://www.cnblogs.com/lz2017/p/6775458.html
Copyright © 2011-2022 走看看