Javascript基础(二)

作者: SkyLine7 | 来源:发表于2017-11-26 15:49 被阅读21次

    一.函数
    JS函数有个很大的坑,就是调用时参数可以和定义时不一致,这真是。。。
    并且每个函数执行到return语句时会返回,如果没有写return,默认返回undefined
    有2种典型的定义函数的方式:
    1>.
    function abs(x) {
    if (x >= 0) {
    return x;
    } else {
    return -x;
    }
    }

    2>.
    var abs = function (x) {
    if (x >= 0) {
    return x;
    } else {
    return -x;
    }
    };
    这种方式abs可以视为指向该函数的变量,因为中JS函数也是一个对象。可以理解为将匿名函数赋给变量abs;

    调用函数:我们可以用typeof关键字对参数类型进行检查,类似于java的instanceof
    function abs(x) {
    if (typeof x !== 'number') {
    throw 'Not a number';
    }
    if (x >= 0) {
    return x;
    } else {
    return -x;
    }
    }

    二.arguments关键字
    arguments只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。arguments类似Array但它不是一个Array,这意味着我们不定义任何参数也是可以拿到参数的

    'use strict'
    function foo(x) {
    console.log('x = ' + x); // 10
    for (var i=0; i<arguments.length; i++) {
    console.log('arg ' + i + ' = ' + arguments[i]); // 10, 20, 30
    }
    }
    foo(10, 20, 30);

    function abs() {
    if (arguments.length === 0) {
    return 0;
    }
    var x = arguments[0];
    return x >= 0 ? x : -x;
    }

    abs(); // 0
    abs(10); // 10
    abs(-9); // 9

    arguments的常见用法是用来判断参数个数,如下:

    // foo(a[, b], c)
    // 接收2~3个参数,b是可选参数,如果只传2个参数,b默认为null:
    function foo(a, b, c) {
    if (arguments.length === 2) {
    // 实际拿到的参数是a和b,c为undefined
    c = b; // 把b赋给c
    b = null; // b变为默认值
    }
    // ...
    }

    三.rest参数,(ES6)新增:rest参数只能参数额写在最后,前面用...标识,从运行结果可知,传入的参数先绑定a、b,多余的参数以数组形式交给变量rest,所以,不再需要arguments我们就获取了全部参数。

    function foo(a, b, ...rest) {
    console.log('a = ' + a);
    console.log('b = ' + b);
    console.log(rest);
    }

    foo(1, 2, 3, 4, 5);
    // 结果:
    // a = 1
    // b = 2
    // Array [ 3, 4, 5 ]

    foo(1);
    // 结果:
    // a = 1
    // b = undefined
    // Array []

    四.变量的作用范围与解构赋值
    代码说话,我觉得一看就懂:
    1>
    'use strict';
    function foo() {
    var x = 1;
    x = x + 1;
    }
    x = x + 2; // ReferenceError! 无法在函数体外引用变量x

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

    function bar() {
    var x = 'A';
    x = x + 'B';//AB
    }

    3>
    function foo() {
    var x = 1;
    function bar() {
    var y = x + 1; // bar可以访问foo的变量x!
    }
    var z = y + 1; // ReferenceError! foo不可以访问bar的变量y!
    }

    变量提升:
    'use strict';
    function foo() {
    var x = 'Hello, ' + y;
    console.log(x); //Hello, undefined
    var y = 'Bob';
    }

    foo();

    因此,在函数内部定义的我们可以理解为局部变量,不在任何函数内定义的变量就具有全局作用域,JavaScript默认有一个全局对象window,全局作用域的变量实际上被绑定到window的一个属性:course和访问window.course是一样的

    我们可以这么写:

    // 定义唯一的全局变量MYAPP:
    var MYAPP = {};

    // 定义其他变量:
    MYAPP.name = 'myapp';
    MYAPP.version = 1.0;

    // 定义其他函数:
    MYAPP.foo = function () {
    return 'foo';
    };

    局部作用域:
    这是普通的方式,
    'use strict';
    function foo() {
    for (var i=0; i<100; i++) {
    //
    }
    i += 100; // 仍然可以引用变量i
    }

    ES6中新增了一个关键字:let,用let替代var可以申明一个块级作用域的变量:

    'use strict';
    function foo() {
    var sum = 0;
    for (let i=0; i<100; i++) {
    sum += i;
    }

    console.log(i += 1);   // SyntaxError:
    

    }

    ES6中新增了一个关键字const, 来声明常量:
    'use strict';
    const PI = 3.14;
    PI = 3; // 某些浏览器不报错,但是无效果!
    PI; // 3.14

    ES6还引入了解构赋值,可以同时对一组变量进行赋值:

    'use strict';
    // 如果浏览器支持解构赋值就不会报错:
    var [x, y, z] = ['hello', 'JavaScript', 'ES6'];
    // x, y, z分别被赋值为数组对应元素:
    console.log('x = ' + x + ', y = ' + y + ', z = ' + z);

    以及嵌套的解构赋值:
    let [x, [y, z]] = ['hello', ['JavaScript', 'ES6']];
    x; // 'hello'
    y; // 'JavaScript'
    z; // 'ES6'

    ES6中的解构赋值还可以忽略某些元素:
    let [, , z] = ['hello', 'JavaScript', 'ES6']; // 忽略前两个元素,只对z赋值第三个元素
    z; // 'ES6'

    对于对象也可以结构赋值:
    'use strict';
    var person = {
    name: '小明',
    age: 20,
    gender: 'male',
    passport: 'G-12345678',
    school: 'No.4 middle school'
    };
    var {name, age, passport} = person;
    // name, age, passport分别被赋值为对应属性:
    console.log('name = ' + name + ', age = ' + age + ', passport = ' + passport);

    还可以设置默认值:
    var person = {
    name: '小明',
    age: 20,
    gender: 'male',
    passport: 'G-12345678'
    };
    // 如果person对象没有single属性,默认赋值为true:
    var {name, single=true} = person;
    name; // '小明'
    single; // true

    解构赋值典型应用场景:
    1.交换2个数的值:
    var x=1, y=2;
    [x, y] = [y, x]

    2.获取当前页面的域名和路径:
    var {hostname:domain, pathname:path} = location;

    五.对象的方法,例子如下:
    var xiaoming = {
    name: '小明',
    birth: 1990,
    age: function () {
    var y = new Date().getFullYear();
    return y - this.birth;
    }
    };
    xiaoming.age; // function xiaoming.age()
    xiaoming.age(); // 今年调用是25,明年调用就变成26了

    2.在一个方法内部,this是一个特殊变量,它始终指向当前对象,也就是xiaoming这个变量。所以,this.birth可以拿到xiaoming的birth属性。(象java中的this)
    var xiaoming = {
    name: '小明',
    birth: 1990,
    age: getAge
    };
    function getAge() {
    var y = new Date().getFullYear();
    return y - this.birth;
    }
    xiaoming.age(); // 25, 正常结果
    getAge(); // NaN

    but,如果以对象的方法形式调用,比如xiaoming.age(),该函数的this指向被调用的对象,也就是xiaoming,这是符合我们预期的。
    如果单独调用函数,比如getAge(),此时,该函数的this指向全局对象,也就是window。
    所以说,弱类型语言还是很坑爹~
    因此我们一般调用对象的方法必须用obj.xxx()的形式!

    我们的结论是,this,在非strict模式下,如果在函数定义的外部,它指向全局对象window;在strict模式下,如果在函数定义的外部,它指向undefined;

    六:高阶函数:
    JS的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
    'use strict';
    function add(x, y, f) {
    return f(x) + f(y);
    }
    var x = add(-5, 6, Math.abs); // 11
    console.log(x);

    sort()函数是一个高阶函数,他的运用如下:
    'use strict';
    var arr = [10, 20, 1, 2];
    arr.sort(function (x, y) {
    if (x < y) {
    return -1;
    }
    if (x > y) {
    return 1;
    }
    return 0;
    });
    console.log(arr); // [1, 2, 10, 20]

    七.JS的闭包:跳过。。。(暂时不想看)
    八.箭头函数(ES6新增):跳过,估计现在遇不到
    九.generator(生成器)(ES6新增)引入的新的数据类型:跳过,估计现在遇不到

    十.JS中的包装对象:类似java中int 和 Integer 的关系
    var n = new Number(123); // 123,生成了新的包装类型
    var b = new Boolean(true); // true,生成了新的包装类型
    var s = new String('str'); // 'str',生成了新的包装类型

    上面三个变量已经成了object。
    总结两点:
    1.没事别用什么new String(),new Number()这些骚操作。。。老老实实用变量直接赋值=.=
    2.用parseInt()或parseFloat()来转换任意类型到number;

    先到这里。。。=.=

    相关文章

      网友评论

        本文标题:Javascript基础(二)

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