zoukankan      html  css  js  c++  java
  • 一些很经典的JavaScript的问题

    1、作用域

    (function() {
    	var a = b = 5;
    })();
    console.log(b);
    

    输出:5

    陷阱是,在函数表达式中有两个赋值,但a是用关键字var 来声明的,这意味着a是局部变量,而b则被赋予为全局变量。另一个陷阱是,它并没有使用严格模式(use strict)。在函数里面,如果启用了严格模式,代码就会报错:“Uncaught ReferenceError: b is not defined”。请记住,严格模式需要你显式地引用全局作用域,代码应该写成:

    (function() {
    	'use strict';
    	var a = window.b = 5;
    })();
    console.log(b);
    

    2、创建“内置”方法

    给String对象定义一个repeatify方法。该方法接收一个整数参数,作为字符串重复的次数,最后返回重复指定次数的字符串。例如:

    console.log('hello'.repeatify(3));
    

     输出的是

    hellohellohello
    

     一个可行的做法如下:

    String.prototype.repeatify = String.prototype.repeatify || function(times) {
    	var str = '';
    	for (var i = 0; i < times; i++) {
    		str += this;
    	}
    	return str;
     
    };
    

    这个测试开发者对Javascript的继承及原型属性的知识,它同时也检验了开发者是否能扩展内置数据类型的方法。 这里的另一个关键点是,看你怎样避免重写可能已经定义了的方法。这可以通过在定义自己的方法之前,检测方法是否已经存在

    String.prototype.repeatify = String.prototype.repeatify || function(times) {
    /* code here */
    };
    

    3、上下文,声明提前

    下面这段代码的结果是什么?为什么?

    function test() {
    	console.log(a);
    	console.log(foo());
    	var a = 1;
    	function foo() {
    		return 2;
    	}
    }
    test();
    

    代码的运行结果:undefined和 2

    理由是,JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里,变量和函数的声明都被提前至函数体的顶部,而同时变量并没有被赋值。因此,当打印变量a时,它虽存在于函数体(因为a已经被声明),但仍然是undefined。换句话说,上面的代码等同于下面的代码:

    function test() {
    	var a;
    	function foo() {
    		return 2;
    	}
    	console.log(a);
    	console.log(foo());
    	a = 1;
    }
    test();
    

     还要明白函数表达式(expression)和函数声明(declaration)的区别

     4、JavaScript中的context和this

    下面代码的运行结果是什么并做解释

    var fullname = 'John Doe';
    var obj = {
    	fullname: 'Colin Ihrig',
    	prop: {
    			fullname: 'Aurelio De Rosa',
    			getFullname: function() {
    				return this.fullname;
    			}
    	}
    };
    console.log(obj.prop.getFullname());
    var test = obj.prop.getFullname;
    console.log(test());
    

    代码输出:Aurelio De Rosa 和 John Doe

    理由是,Javascript中关键字this所指代的函数上下文,取决于函数是怎样被调用的,而不是怎样被定义的。

    在第一个console.log(),getFullname()被作为obj.prop对象被调用。因此,当前的上下文指代后者,函数返回这个对 象的fullname属性。相反,当getFullname()被赋予test变量,当前的上下文指代全局对象window,这是因为test被隐式地作 为全局对象的属性。基于这一点,函数返回window的fullname,在本例中即为代码的第一行。

    如果说想要实现和第一次输出一样的效果,还可以这样写

    console.log(test.call(obj.prop));
    
    var test = obj.prop.getFullname.bind(obj.prop);
    console.log(test());
    

    通常有一些老的浏览器是不支持bind函数,我们可以使用apply和call

    Function.prototype.bind = Function.prototype.bind || function(context){
      var self = this;
      return function(){
        return self.apply(context, arguments);
      };
    }
    

     5、Overlay库

    对于overlay covers,最好使用 position: fixed 而不是 position: absolute,这样即使窗口滚动的时候也可以保证层铺满整个窗口

    .overlay {
      position: fixed;
      left: 0;
      right: 0;
      bottom: 0;
      top: 0;
      background: rgba(0,0,0,.8);
    }
    

    从把内容放置到层的中心位置的方式也可以

    .overlay article {
      position: absolute;
      left: 50%;
      top: 50%;
      margin: -200px 0 0 -200px;
       400px;
      height: 400px;
    }
    

    实现单击关闭层的功能,可以为层设置一个事件监听器

    $('.overlay').click(closeOverlay);
    

     看着是对的,但很快你就会发现在这个层的子元素上单击也会关闭层,这明显不是我们预期的效果。解决方法是先检查事件的targets来确保不是一个传播事件,像这样:

    $('.overlay').click(function(e){
      if (e.target == e.currentTarget)
        closeOverlay();
    });
    
  • 相关阅读:
    Android内存优化4 了解java GC 垃圾回收机制2 GC执行finalize的过程
    Android内存优化3 了解java GC 垃圾回收机制1
    Android内存优化2 了解java内存分配 2
    Android内存优化1 了解java内存分配 1
    Android Parcel对象详解
    Android中Parcel的分析以及使用
    Android进阶笔记:Messenger源码详解
    Android进阶笔记:AIDL内部实现详解 (二)
    Android进阶笔记:AIDL内部实现详解 (一)
    Android开发高级进阶——多进程间通信
  • 原文地址:https://www.cnblogs.com/chenpingzhao/p/4765246.html
Copyright © 2011-2022 走看看