zoukankan      html  css  js  c++  java
  • js问题学习

    1.前言为了node.js做准备,js的基本功还是很重要的。所以正值1024程序员节的时候所以找了些题目,整理了一下知识点。这篇文章感觉代码太多,难免枯燥,所以文章最后留了个彩蛋给读者。

    2.简单回调

    代码

    function foo(){

    console.log(this.a);

    }

    function doFoo(fn){

    fn();

    }

    function doFoo2(o){

    o.foo();

    }

    var obj = {

    a: 2,

    foo: foo

    };

    var a = "I'm an a";

    doFoo(obj.foo);

    doFoo2(obj);

     

    分析

    在Javascript中,this指向函数 执行时的当前对象,而非声明环境y有
    执行doFoo的时候执行环境就是doFoo函数,执行环境为全局。
    执行doFoo2时是在对象内部调用函数,this指针指向该对象。
    结果

    I'm an a

    2

    3、用apply改变函数作用域

    代码

    function foo(somthing){

    console.log(this.a, somthing);

    }

    function bind(fn, obj){

    return function(){

    return fn.apply(obj, arguments);

    }

    }

    var obj = {

    a:2

    }

    var bar = bind(foo, obj);

    var b = bar(3);

     

    分析

    apply、call、bind都有个作用就是改变作用域,这里用apply将foo函数的作用域指向obj对象,同时传入参数。
    再简单分析一下bind函数内部的嵌套,执行bind函数的时候返回的是一个匿名函数,所以执行bar(3)的时候实际上是执行的bind内部的匿名函数,返回的是之前传入的foo函数的执行结果。
    函数没有返回值的情况下默认返回undefined。
    结果

    2 3

    undefined


    4.new关键字

    function foo(a,b){

    this.val = a+b;

    }

    var bar = foo.bind(null, 'p1');

    var baz = new bar('p2');

    console.log(baz.val);

    console.log(b);

    分析

    bind函数的第一个参数为null代表作用域不变,后面的不定参数将会和函数本身的参数按次序进行绑定,绑定之后执行函数只能从未绑定的参数开始传值。

    结果

    p1p2


    5.自执行函数

    function foo(){

    console.log(this.a);

    }

    var a = 2;

    var o = {a:3,foo:foo};

    var p = {a:4};

    (p.foo=o.foo)();

     

    分析

    经常可以看到这样的代码

    (function(){

    //...

    })()


    这种代码通常是创建一个立即执行的函数同时避免污染全局变量。
    很少有人去关注赋值语句执行之后会返回什么结果,其实就是返回当前值。也就是说当括号内执行完赋值之后,返回的是o对象中的foo函数。函数的执行环境中有一个a对象,嗯,就是它了~
    答案

    2


    6.变量属性

    var a = [];

    a[0] = 1;

    a['foobar'] = 2;

    console.log(a.length);

    console.log(a.foobar);

    分析

    当一个变量被声明后,扩充其属性并不会改变原数据类型。

    结果

    1

    2

     

    7.精度问题

    var a = 'foo';

    a[1] = 'O';

    console.log(0.1+0.2==0.3||a);

    分析

    当操作小数时请小心,js的小数计算并不精确,所以上面的判断是false。

    字符串变量是常量。

    结果

    foo


    8.命名提升

    foo();

    var foo = 0;

    function foo(){

    console.log(1);

    }

    foo = function(){

    console.log(2);

    };

    分析

    声明的变量和命名函数都会被提升到代码的最前面,只不过声明的变量的赋值语句在代码中的位置不变。所以上面这段代码应该被理解为:

    var foo;

    function foo(){

    console.log(1);

    }

    foo();

    foo = 0;

    foo = function(){

    console.log(2);

    };

    结果

    1

    思考

    foo();

    var foo = 0;

    function foo(){

    console.log(1);

    }

    foo();

    foo = function(){

    console.log(2);

    };

    foo();

    上面代码的结果:

    1

    报错

    9、作用域

    foo();

    var a = true;

    if(a){

    function foo(){

    console.log('a');

    }

    } else {

    function foo(){

    console.log('b');

    }

    }

    分析

    javascript并不是以代码段为作用域,而是以函数。
    再根据命名提升的原则,所以这段代码应该是这样的:

    function foo(){

    console.log('a');

    }

    function foo(){

    console.log('b');

    }

    foo();

    var a = true;

    if(a){

    } else {

    }

    结果

    b

    10.闭包陷阱

    for(var i=1;i<=5;i++){

    setTimeout(function(){

    console.log(i);

    }, i*1000);

    }

    分析

    闭包有个重要的作用就是,在内层函数引用外层函数定义的变量时,外层函数的变量不会被会被持久化。

    这里有个隐藏陷阱就是for循环结束之后i仍然自增了1。
    结果

    6

    6

    6

    6

    6


    11.伪闭包

    function foo(){

    console.log(a);

    }

    function bar () {

    var a = 3;

    foo();

    }

    var a = 2;

    bar();

    分析

    闭包是函数的嵌套定义,而不是函数的嵌套调用。
    结果

    2

    思考

    如何输出3?

    function bar () {

    function foo(){

    console.log(a);

    }

    var a = 3;

    foo();

    }

    var a = 2;

    bar();

    12.彩蛋光说不练假把式~
    一周月内将下题正确答案发送至我邮箱内(邮箱地址请参考博客),将获得本年度我阅读过最优秀的关于AngularJS的电子书一本。

    var Obj = {

    name: 'zdl',

    do: function(){

    console.log(this.name);

    }

    }

    写个对象a继承Obj的方法(不使用new)。

    原文作者:亚里士朱德
    博客网址:http://yalishizhude.github.io

  • 相关阅读:
    关于PHP程序员技术职业生涯规划
    让PHP7达到最高性能的几个Tips
    php-fpm解读-进程管理的三种模式 及 worker进程、master进程详解
    CGI、FastCGI和php-fpm概念和区别
    什么是PHP7中的孤儿进程与僵尸进程,加上守护进程
    PHP 信号管理知识整理汇总
    PHP多进程---fork多个子进程,父进程阻塞与非阻塞
    锁存器、触发器和寄存器
    FPGA基础之锁存器与触发器的设计
    从CMOS到触发器(二)
  • 原文地址:https://www.cnblogs.com/wangjiaojiao/p/4936636.html
Copyright © 2011-2022 走看看