• JavaScript学习笔记


    基础知识

    1、this是在函数运行时生成的一个内部对象:

    1. 只能在函数内部使用。
    2. 代表调用函数的那个对象。
    3. 在构造方法中调用时,指向新生成的对象。

    2、由于JS不是面向对象,那么要做到模块化就需要用到一些技巧来实现下面这些目的:

    1. 不能污染全局变量。
    2. 不能暴露所有成员,而且模块内部的成员不能被外部的代码修改。

    如果是只有一个小文件的话在一个文件中没什么问题,但是在大工程中模块的作用就非常重要了。在CommonJS中,有一个全局的require方法来完成模块的加载(在很多组件中能看到这种用法):

    // 第一个参数为所需要的模块数组,第二个参数为回调函数。
    require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){
    	// 回调函数的代码。
    });
    

    3、在实现模块化的时候一般会用到立即执行函数,直观上来看应该叫匿名立即执行的函数,一般有两种写法:

    (function () { /* code */ } ());
    (function () { /* code */ })();
    

    应该是在括号中的东西被当做是要用的参数,所以才会立即执行吧。

    4、闭包

    这里是阮一峰老师对闭包的定义:闭包就是能够读取其他函数内部变量的函数。能达到的效果就是让这些变量的值保存在内存中,来看一个例子:

    	var obj = function () {
    		var a = '';
    		return {
    			set: function (val) {
    				a = val;
    			},
    			get: function () {
    				return a;
    			}
    		}
    	};
    	var b = obj();
    	b.set('new val');
    	alert(b.get());// new val
    

    按照正常的情况方法的东西都会在执行完成后被回收掉,但是由于set&get方法中保持了引用,所以此时并不会销毁。这里有另外一个专业解释:

    闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。

    各种理解之间有点差别。

    其他

    模块化

    在JS定义的方法、变量都将作为全局变量,如果都这么搞的话大家做各种JS包之间的冲突将会非常严重,而且如果想将JS用在后端编程,模块化是必须的。简单地用立即执行函数定义模块如下:

    var module1 = (function(){
    	var _count = 0;
    	var m1 = function(){ /* code */};
        var m2 = function(){ /* code */};
        return {
    		m1 : m1,
    		m2 : m2
    	};
    })();
    

    模块化除了分离各个部分,还需要考虑如何防止其他人修改模块中的方法和属性,更多可以看这里。在使用模块上面有两个规范:CommonJSAMD,在CommonJS中有一个全局的require方法来加载模块:

    var math = require('math');
    math.add(2,3);

    这样做最大的问题在于math.add需要在math模块加载完成之后才能执行,在浏览器端显然这是没办法接受的。AMD(Asynchronous Module Definition:异步模块定义)就是应对这种场景产生的,采用异步方式加载模块,模块的加载不影响后面语句的执行,而依赖于此模块的语句放在回调函数中以便模块加载完成之后执行:

    require([module], callback);

    其中module是要加载的模块,callback则是加载成功之后执行的回调函数。下面来看一个阮一峰老师的例子: 

    // 在同级目录下新建main.js
    define(function (){
    	var add = function (x,y){
    		return x+y;
    	};
    	return {
    		add: add
    	};
    });
    // 在页面上加载模块
    require(['./math'], function (math){
    	alert(math.add(1,1));
    });
    

    使用require.js的地址在这里。如果要定义的模块还依赖其他模块,那么define的第一个参数可以用来指定:

    define(['myLib'], function(myLib){/* code */ }

    另外可以用require.js来加载非规范的模块定义,可以看这里

    PS:太多的JS都是用了模块化,看完了几篇文章有了一点大致的了解了(2015/1/23)。

    jQuery

    这是目前使用最广泛的一个JavaScript函数库,简化了很多前端开发,而且使得代码的可读性提高了一大截,下面来看简单的用法:

    $(document) //选择整个文档对象
    $('a:first') //选择网页中第一个a元素
    $('div').has('p'); // 选择包含p元素的div元素
    $('div').parent(); //选择div元素的父元素
    $('div').find('h3').eq(2).html('Hello');// 链式操作
    $('h1').html('Hello'); //html()有参数Hello,表示对h1进行赋值
    $('div').insertAfter($('p'));// 插入元素
    $('<li class="new">new list item</li>');// 创建元素
    // 绑定事件
    $('input').bind(
    	'click change', //同时绑定click和change事件
    	function() {
    		alert('Hello');
    	}
    );
    

    另外还可以实现一些特殊效果,这里有jQuery的API文档,虽然jQuery用起来很爽,但是对性能、资源的消耗较大,也要慎重使用(可以参考这里),既然用jQuery对性能有损耗,如果我们做一些简单的功能,那么是不需要用jQuery的,而且jQuery太大的,网络不好的时候有点头疼,解决办法是用一些JavaScript原生的方法来代替jQuery:

    function request(type, url, opts, callback) {
    	var xhr = new XMLHttpRequest();
    	if (typeof opts === 'function') {
    		callback = opts;
    		opts = null;
    	}
    	xhr.open(type, url);
    	var fd = new FormData();
    	if (type === 'POST' && opts) {
    		for (var key in opts) {
    			fd.append(key, JSON.stringify(opts[key]));
    		}
    	}
    	xhr.onload = function () {
    		callback(JSON.parse(xhr.response));
    	};
    	xhr.send(opts ? fd : null);
    }
    

    这样简单地对原生的请求包装一下也能达到类似Ajax的效果(更多可以看这里),另外还有很多jQuery的替代方法,比如zepto.js

    PS:很多工具用起来都会有副作用,要多思考利弊(2015/1/25)。

    ------ update ------

  • 相关阅读:
    分享一个小故事
    思维局限
    java程序员笑不死的经历ส้้้้้้้้้
    一些话
    定位 java虚拟机内存问题 个人总结
    关于分布式事务、两阶段提交协议、三阶提交协议(转)
    maven常用配置信息和常量
    Mybatis-常见SQL语句示例
    Redis主从同步原理-SYNC
    B+树在mysql数据库索引中的使用
  • 原文地址:https://www.cnblogs.com/antispam/p/4222479.html
Copyright © 2020-2023  润新知