博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript全面学习(函数)
阅读量:4628 次
发布时间:2019-06-09

本文共 10058 字,大约阅读时间需要 33 分钟。

1.定义函数的两种方法:

function abs(x) {    if (x >= 0) {        return x;    } else {        return -x;    }}

或者

var abs = function (x) {    if (x >= 0) {        return x;    } else {        return -x;    }};  //记得要加分号,因为这是赋值abs变量

2.调用函数

abs(10, 'blablabla'); // 返回10abs(-9, 10, 'hehe', null); // 返回9,不受多个参数的影响,因为第一个参数就return了abs(); // x为undefined,返回NaN

3.关键字arguments,类似于array.

function foo(x) {    alert(x); // 10    for (var i=0; i

arguments最常用于判断传入参数的个数:

if (arguments.length === 0) //如果参数个数为0...

 

4.用rest获取所有参数:

function foo(a, b) {    var i, rest = [];    if (arguments.length > 2) {        for (i = 2; i

一般写成如下更加简洁明了,与上面等效:

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 []

注意rest前面有3个点,如果没有的话,相当于rest就是第三个参数:

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// 3foo(1);// 结果:// a = 1// b = undefined// undefined

5.接受任意个参数并返回它们的和:

function sum(...rest) {  var sum = 0;  for(var i of rest) {    sum += i;        }  return sum;}

6.JavaScript在行末自动添加分号

7.不同函数内部的同名变量互相独立,互不影响

8.内部函数可以访问外部函数定义的变量,反过来则不行:

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

9.JavaScript会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部,但不会提升变量的赋值:

'use strict';function foo() {    var x = 'Hello, ' + y;    alert(x);    var y = 'Bob';}foo();  //结果显示Hello, undefined,说明y没有值,但是已经声明了

10.JavaScript默认有一个全局对象window,全局作用域的变量实际上被绑定到window的一个属性:

'use strict';var course = 'Learn JavaScript';alert(course); // 'Learn JavaScript'alert(window.course); // 'Learn JavaScript'  与上面等效

11.let解决块级作用域

'use strict';function foo() {    for (var i=0; i<100; i++) {        //    }    i += 100; // 仍然可以引用变量i}
'use strict';function foo() {    var sum = 0;    for (let i=0; i<100; i++) {        sum += i;    }    i += 1; // SyntaxError,无法引用i}

12.关键字const来定义常量,constlet都具有块级作用域:

'use strict';const PI = 3.14;PI = 3; // 某些浏览器不报错,但是无效果!PI; // 3.14

13.this指的是被调用函数的当前对象  ,多层内嵌会使指示错误,可以在函数开头用var that = this;来捕捉固定this

    要指定函数的this指向哪个对象,可以用函数本身的apply方法,它接收两个参数,第一个参数就是需要绑定的this变量,第二个参数是Array,表示函数本身的参数。

function getAge() {    var y = new Date().getFullYear();    return y - this.birth;}var xiaoming = {    name: '小明',    birth: 1990,    age: getAge};xiaoming.age(); // 25getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空

对普通函数调用,我们通常把this绑定为null

另一个与apply()类似的方法是call(),唯一区别是:

  • apply()把参数打包成Array再传入;

  • call()把参数直接按顺序传入。 

14.map函数用法,()里调用其他函数

function pow(x) {    return x * x;}var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81] 令数组的所有元素都执行()里的函数

还能这样

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];arr.map(String); // ['1', '2', '3', '4', '5', '6', '7', '8', '9']

 15.reduce函数用法:必须接收两个参数,reduce()把结果继续和序列的下一个元素做累积计算,例如求和:

var arr = [1, 3, 5, 7, 9];arr.reduce(function (x, y) {    return x + y;}); // 25

其他例子

var arr = [1, 3, 5, 7, 9];arr.reduce(function (x, y) {    return x * 10 + y;   // 把return值当成下一个x,与下一个y循环函数}); // 13579

16.箭头函数

function (x) {    return x * x;}                 //相当于箭头函数x => x * x

 如果包含多条语句,这时候就不能省略{ ... }return

如果参数不是一个,就需要用括号()括起来:

// 两个参数:(x, y) => x * x + y * y// 无参数:() => 3.14// 可变参数:(x, y, ...rest) => {    var i, sum = x + y;    for (i=0; i

如果要返回一个对象(单表达式),要外加一个括号,写成:

x => ({ foo: x })

回顾前面的例子,

var obj = {    birth: 1990,    getAge: function () {        var b = this.birth; // 1990        var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象        return fn();    }};obj.getAge(); // 25

箭头函数使this总是指向词法作用域,也就是外层调用者obj,如果是之前的直接创建函数,this就会指向window

由于this在箭头函数中已经按照词法作用域绑定了,所以,用call()或者apply()调用箭头函数时,无法对this进行绑定,即传入的第一个参数被忽略

var obj = {    birth: 1990,    getAge: function (year) {        var b = this.birth; // 1990        var fn = (y) => y - this.birth; // this.birth仍是1990        return fn.call({birth:2000}, year);   //箭头函数里的this已经绑定原对象obj,                                                          //  此时的this.birth仍然是1990,                                                     //  而不会将this绑定到传入的 birth:2000    }};obj.getAge(2015); // 25

 

17.split() 方法用于把一个字符串分割成字符串数组,如果要把字符串数组变成“数”组,要乘以1,可以如下写

var arr=string.split('').map(x => x * 1)

18.parseInt()函数可解析一个字符串,并返回一个整数。

    语法:parseInt(string, radix);

    string 必需。要被解析的字符串。

    radix 可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。

    如果省略该参数或其值为 0,则数字将以 10 为基础来解析。

    如果它以 “0x” 或 “0X” 开头,将以 16 为基数。

    如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。

parseInt("10");          //返回 10         10进制parseInt("19",10);       //返回 19 (10+9)  10进制parseInt("11",2);        //返回 3 (2+1)    2进制parseInt("17",8);        //返回 15 (8+7)   8进制parseInt("1f",16);        //返回 31 (16+15)    16进制parseInt("010");         //未定:返回 10 或 8

19.filter方法

var arr = [1, 2, 4, 5, 6, 9, 10, 15];var r = arr.filter(function (x) {       return x % 2 !== 0;    //把arr中的偶数过滤掉,留下x%2!==0的});r; // [1, 5, 9, 15]
var arr = ['A', '', 'B', null, undefined, 'C', '  '];var r = arr.filter(function (x) {    return x && x.trim(); // 把false的空字符串过滤掉});                            //注意:IE9以下的版本没有trim()方法arr; // ['A', 'B', 'C']
var arr = ['A', 'B', 'C'];var r = arr.filter(function (element, index, self) {  // 可以输入3个参数    console.log(element); // 依次打印'A', 'B', 'C'    console.log(index); // 依次打印0, 1, 2    console.log(self); // self就是变量arr   会输出3次Array [ "A", "B", "C" ]    return true;});
var r = arr.filter(function (element, index, self) {    return self.indexOf(element) === index;});  //过滤掉arr中重复的元素   indexOf() 方法返回某个指定的字符串值在字符串中首次出现的位置,注意是首次

选出数组里面的素数:

function get_primes(arr) {      var i;      var res = arr.filter(function(x){            if(x<2) return false;     //排除掉1            for(i=2; i*i<=x; i++){                     if(x%i === 0){
return false;} //从2开始往上面的数一个个地除,直到确认是不是素数 } return true; //是素数就return true。 }); return res;}

 20.对于两个元素xy,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1

21.闭包(不大懂意义):返回一个函数,不立即执行

function lazy_sum(arr) {    var sum = function () {        return arr.reduce(function (x, y) {            return x + y;        });    }    return sum;}var f = lazy_sum([1, 2, 3, 4, 5]); // function sum()                          //调用lazy_sum()时,返回的并不是求和结果,而是返回求和函数f(); // 15       //调用函数f时,才是真正计算求和的结果

当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数(每次调用的结果互不影响):

var f1 = lazy_sum([1, 2, 3, 4, 5]);var f2 = lazy_sum([1, 2, 3, 4, 5]);f1 === f2; // false

返回的函数并没有立刻执行,而是直到调用了f()才执行:

function count() {    var arr = [];    for (var i=1; i<=3; i++) {     // 这里正常思维是最终i=4,但是没想到4最后居然进入循环里面运算了??最终return 4*4        arr.push(function () {            return i * i;        });    }    return arr;}var results = count();var f1 = results[0];var f2 = results[1];var f3 = results[2];f1(); // 16f2(); // 16f3(); // 16   等到3个函数都返回时,它们所引用的变量i已经变成了4

正确写法:

function count() {    var arr = [];    for (var i=1; i<=3; i++) {        arr.push((function (n) {     // 在里面再创建一个函数,用该函数的参数绑定循环变量当前的值            return function () {                return n * n;            }        })(i));              // 这样是用i去立即执行函数 注意括号的括法,(function (x) { return x * x }) (i);    }    return arr;}var results = count();var f1 = results[0];var f2 = results[1];var f3 = results[2];f1(); // 1f2(); // 4f3(); // 9

借助闭包,可以封装一个私有变量。例如用JavaScript创建一个计数器:

'use strict';function create_counter(initial) {    var x = initial || 0;   //在没有初始值initial的时候给一个初始值    return {        inc: function () {            x += 1;            return x;        }    }}var c1 = create_counter();c1.inc(); // 1c1.inc(); // 2c1.inc(); // 3var c2 = create_counter(10);c2.inc(); // 11c2.inc(); // 12c2.inc(); // 13

换句话说,闭包就是携带状态的函数,并且它的状态可以完全对外隐藏起来:

function make_pow(n) {    return function (x) {        return Math.pow(x, n);   // 计算x的n次方    }}// 创建两个新函数:var pow2 = make_pow(2);var pow3 = make_pow(3);pow2(5); // 25             相当于Math.pow(5, 2)pow3(7); // 343            相当于Math.pow(7, 3)

只需要用函数,就可以用计算机实现运算,而不需要0123这些数字和+-*/这些符号:

'use strict';// 定义数字0:var zero = function (f) {    return function (x) {        return x;    }};// 定义数字1:var one = function (f) {    return function (x) {        return f(x);    }};// 定义加法:function add(n, m) {    return function (f) {        return function (x) {            return m(f)(n(f)(x));        }    }}// 计算数字2 = 1 + 1:var two = add(one, one);// 计算数字3 = 1 + 2:var three = add(one, two);// 计算数字5 = 2 + 3:var five = add(two, three);// 给3传一个函数,会打印3次:(three(function () {    console.log('print 3 times');}))();// 给5传一个函数,会打印5次:(five(function () {    console.log('print 5 times');}))();

22.(意义不明啊!)generator(生成器)是ES6标准引入的新的数据类型。一个generator看上去像一个函数,但可以返回多次。

    编写一个产生斐波那契数列的函数:

function* fib(max) {    //注意多出的*号    var        t,        a = 0,        b = 1,        n = 1;    while (n < max) {        yield a;        t = a + b;        a = b;        b = t;        n ++;    }    return a;}fib(5); // fib {[[GeneratorStatus]]: "suspended", [[GeneratorReceiver]]: Window}        // fib(5)仅仅是创建了一个generator对象,还没有去执行它 //可以这样调用:var f = fib(5);f.next(); // {value: 0, done: false}f.next(); // {value: 1, done: false}f.next(); // {value: 1, done: false}f.next(); // {value: 2, done: false}f.next(); // {value: 3, done: true}

next()方法每次遇到yield x;就返回一个对象{value: x, done: true/false},然后“暂停”。返回的value就是yield的返回值,done表示这个generator是否已经执行结束了。

一般这样调用:

for (var x of fib(6)) {   // 注意要6,坑啊    console.log(x); // 依次输出0, 1, 1, 2, 3}

下面是天书:

用generator的话,AJAX可以大大简化代码:

try {    r1 = yield ajax('http://url-1', data1);    r2 = yield ajax('http://url-2', data2);    r3 = yield ajax('http://url-3', data3);    success(r3);}catch (err) {    handle(err);}

用一个对象来保存状态:

var fib = {    a: 0,    b: 1,    n: 0,    max: 5,    next: function () {        var            r = this.a,            t = this.a + this.b;        this.a = this.b;        this.b = t;        if (this.n < this.max) {            this.n ++;            return r;        } else {            return undefined;        }    }};

自增,并保存数字:

'use strict';function* next_id() {var i=1;while(true){  yield i++;}}

 

转载于:https://www.cnblogs.com/shen076/p/6160173.html

你可能感兴趣的文章
【整理】C#文件操作大全(SamWang)
查看>>
如何从数据库生成 EF Code First model
查看>>
2013年3月4号
查看>>
QT Creator 快速入门教程 读书笔记(一)
查看>>
CNN之yolo目标检测算法复习总结
查看>>
Windows系统架构
查看>>
PCA的数学原理
查看>>
Flask Web Development —— Web表单(上)
查看>>
Struts2标签
查看>>
PHP知识结构
查看>>
extjs grid renderer用法
查看>>
PAT Basic 1072
查看>>
作业分析,Karger最小割:(python)Engineering: Algorithms1 - SELF PACED Algorithms: Design and Analysis...
查看>>
[JS-JQuery]基础
查看>>
“cyl projection cannot cross pole” 解决方法
查看>>
[亲测]在Mac下配置php开发环境:Apache+php+MySql
查看>>
mono修改配置
查看>>
Vue 环境搭建(win10)
查看>>
iOS7系统iLEX RAT冬青鼠安装教程:无需刷机还原纯净越狱系统
查看>>
typeof操作符的返回值
查看>>