JavaScript必须了解的知识点总结。

整理的知识点不全面但是很实用。

主要分三块:

(1)JS代码预解析原理(包括三个段落);

(2)函数相关(包括 函数传参,带参数函数的调用方式,闭包);

(3)面向对象(包括 对象创建、原型链,数据类型的检测,继承)。

JS代码预解析原理

/****************** JS代码预解析原理 ******************//*JS代码预解析、变量作用域、作用域链等 应该能作为学习JS语言的入门必备知识。下边给出些简要解释和一些典型的代码段,若要了解更多,能从网上搜索到更多相关示例。

引用网上的一段有关 “JS的执行顺序” 的解释:如果一个文档流中包含多个script代码段(用script标签分隔的js代码或引入的js文件),它们的运行顺序是:步骤1. 读入第一个代码段(js执行引擎并非一行一行地执行程序,而是一段一段地分析执行的)步骤2. 做语法分析,有错则报语法错误(比如括号不匹配等),并跳转到步骤5步骤3. 对var变量和function定义做“预解析”(永远不会报错的,因为只解析正确的声明)步骤4. 执行代码段,有错则报错(比如变量未定义)步骤5. 如果还有下一个代码段,则读入下一个代码段,重复步骤2步骤6. 结束*/// 下边给出 三段觉得比较典型的代码示例:/********** 一:基本的几条语句 **********/alert(num);  // undefinedvar num = 0;alert(str);  // 错误:str未定义str = "string";    alert(func);  // undefinedvar func = function (){ alert(‘exec func‘); }test();  // exec testalert(test());  // 先exec test 后undefinedfunction test(){ alert(‘exec test‘); }

/********** 二:函数名与变量名相同 **********/        //var mark = 1;function mark(x) {  return x * 2;}var mark;alert(mark);  // function mark(x) {   return x * 2; }// 去掉前边的var mark = 1;则会返回1

/********** 三:把第二段包括在语句块中 **********/    // 当有条件时候(代码包含在条件语句块里)if (false) {    var mark1 = 1;    function mark1() {       alert("exec mark1");    }    //var mark1;    alert(mark1);  }alert(mark1);mark1();// 由于解析浏览器解析不同,这段代码在不同浏览器里执行的结果不一致,具体原因可从网上查找答案

函数相关(包括 函数传参,带参数函数的调用方式,闭包)

/****************** 函数相关 ******************/

/********** 一:函数传参 **********/    /*编程语言大概都有 值类型与引用类型 的区别,JS也不例外。原始类型:undefined  null number boolean 均为值类型。string比较特殊,因为它是不可改变的,String类定义的方法都不能改变字符串的内容。function object array 这三种为引用类型。 *//* JavaScript 函数传递参数时,是值传递。

ECMAScript 中,所有函数的参数都是按值来传递的。基本类型值的传递和基本类型变量复制一致(采用在栈内新建值),引用类型值的传递和引用类型变量的复制一致(栈内存放的是指针,指向堆中同一对象)。具体参考:http://www.xiaoxiaozi.com/2010/03/05/1719/*/function setName(obj){    //obj拷贝了person的值(person是一个对象的引用地址),所以obj也指向了person所指向的对象。    obj.name = "xiaoxiaozi";     obj = {}; // 让obj 指向了另一个对象    obj.name = "admin";}var person = {};setName(person);alert(person.name); //  xiaoxiaozi

/********** 二:带参数函数的调用方式 **********/    /* 在DOM不同版本中,函数调用方式不太一样。标准推荐的是addEventListener和attachEvent    这两种方式有很多资料可查。但是有些已经不被推荐的函数调用仍旧有实际应用,相关资料发现的不多。    这里主要讨论这些函数调用方式*/var g = "全局变量";function show(str) {    alert("my site: " + str);}setTimeout("show(g);",100);  // g是全局变量,函数正确执行function t() {    var url = "www.xujiwei.cn";    var num = 2;    //setTimeout("alert("+url+")", 3000);    //   解析错误,www未定义    //setTimeout("alert("+num+")", 3000);    //   解析正确,注意与上句对比    //setTimeout("show(‘url‘);", 2000);    //   url    //setTimeout("show("+ url +");", 2000);    //   解析错误,www未定义    //setTimeout("show(url);", 2000);    //   解析错误,url未定义    //setTimeout(‘"show("+ url +");"‘, 2000);    //   解析错误,url未定义    //setTimeout("show(‘"+ url +"‘);", 2000);    // 正确    //setTimeout(function(){show(url);},1000);   // 正确}t();/* 结论:    诸如onclick="xx();"等函数调用方式,在双引号内的内容直接解析为js语句执行。    若调用的函数带有参数,注意对比以上各种写法,保证传递进去的参数为正确的。*/        

/********** 三:闭包 **********//* 闭包,几乎是每个学习JS的朋友都要讨论的问题,因此各种相关资料应有尽有。它的作用很大,但也有弊端,例如如果使用不当,容易引起内存泄漏等问题,因此有不少人提倡少用闭包。

这里列出闭包的一种经典应用,一个有争议的应用。*/function test1() {     //通过闭包,每次能传入不同的j值。    for (var j = 0; j < 3; j++) {        (function (j) {            setTimeout(function () { alert(j) }, 3000);        })(j);                                                     }}test1();/* 这个是闭包的典型应用 */

(function tt() {    for (var i = 1; i < 4; i++) {        document.getElementById("b" + i).attachEvent("onclick",         new Function(‘alert("This is button‘ + i + ‘");‘)); // 在IE中测试    }})()  // 立即执行函数,一个文件是否只能有一个?把上边函数写成立即执行出问题,怎么回事?

/* 这个问题出现在论坛里,有很多争议有说是new Function动态生成个闭包结构的函数,所以能保存外部变量。有说是跟闭包无关,new Function,就是新定义了一个function,i的值也作为这个新的function的参数固化在其内部了。*/        

面向对象(包括 对象创建、原型链,数据类型的检测,继承)

/****************** 面向对象 ******************/

/********** 一:对象创建、原型链 **********//* 讨论 构造函数(类方式)创建对象 ,深入理解这些内容,是很重要的*/function MyFunc() { }; //定义一个空函数var anObj = new MyFunc(); //使用new操作符,借助MyFun函数,就创建了一个对象// 等价于:function MyFunc() { };var anObj = {};     //创建一个对象anObj.__proto__ = MyFunc.prototype;MyFunc.call(anObj); //将anObj对象作为this指针调用MyFunc函数/*用 var anObject = new aFunction() 形式创建对象的过程实际上可以分为三步:第一步:建立一个新对象(anObject);第二步:将该对象内置的原型对象(__proto__)设置为构造函数prototype引用的那个原型对象;第三步:将该对象作为this参数调用构造函数,完成成员设置等初始化工作。

对象建立之后,对象上的任何访问和操作都只与对象自身及其原型链上的那串对象有关,与构造函数再扯不上关系了。换句话说,构造函数只是在创建对象时起到介绍原型对象和初始化对象两个作用。

原型链:(参考:http://hi.baidu.com/fegro/blog/item/41ec7ca70cdb98e59152eed0.html)    每个对象(此处对象应该仅指大括号括起来的object,不包括function、array。待验证?)    都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性时,    如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,    这个__proto__又会有自己的__proto__,于是就这样 一直找下去,也就是我们平时所说的原型链的概念。*/ 

/* 理解了对象创建的原理,可试着分析下边两个示例的结果 */var yx01 = new function() {return "圆心"}; alert(yx01); // [object Object]var yx02 = new function() {return new String("圆心")}; alert(yx02); // “圆心”        /* 解释:"圆心"是基本的字符串类型,new String("圆心")则创建了一个string对象。只要new表达式之后的构造函数返回一个引用对象(数组,对象,函数等),都将覆盖new创建的对象,如果返回一个原始类型(无 return 时其实为 return 原始类型 undefined),那么就返回 new 创建的对象。参考:http://www.planabc.net/2008/02/20/javascript_new_function/ */

/********** 二:数据类型的检测 **********//* 判断数据类型可能想到的方法:constructor、typeof、instanceof、Object.prototype.toString.call()*//***** 1、通过constructor属性  *****/var myvar= new Array("a","b","c","d");function A(){}myvar.constructor = A;var c = myvar.constructor;alert(c); // function A(){}//可见,通过constructor属性获取类型的方法很容易被修改,不应该用来判断类型。

/***** 2、通过typeof  *****//*     typeof是一个操作符,而不是个函数。    typeof的实际应用是用来检测一个对象是否已经定义或者是否已经赋值。        如if(typeof a!="undefined"){},而不要去使用if(a)因为如果a不存在(未声明)则会出错。    typeof检测对象类型时一般只能返回如下几个结果:    number,boolean,string,function,object,undefined。    对于Array,Null,自定义对象 等使用typeof一律返回object,        这正是typeof的局限性。*/var num = new Number(1);var arr = [1,2,3];alert(typeof num);  //object 而不是numberalert(typeof arr);  //object 而不是Arrayalert(typeof null);  // object

/***** 3、通过 instanceof  *****//* 用instanceof操作符来判断对象是否是某个类的实例。    如果obj instanceof Class返回true,那么Class的原型与obj原型链上的某个原型是同一个对象,    即obj要么由Class创建,要么由Class的子类创建。*/function t(){};t.prototype  = Array.prototype;//t.prototype  = [];var x = new t();alert(x instanceof t);//弹出truealert(x instanceof Array);//弹出truealert(x instanceof Object);//弹出true/*由此可知,通过 instanceof 判断数据类型也不可靠。因为一个对象(此处x)的原型链可以很长,每个原型的类型可以不同。

另外在iframe内也会容易出错:即有个页面定义了一个数组a,页面又嵌套了一个IFrame,在Iframe里面通过 top.a instanceof Array, 是返回false的。这个说明 父页面和内嵌iframe里的对象是不同的,不能混合在一起使用。改成top.a instanceof top.Array 就会返回true*/

/***** 4、通过 Object.prototype.toString.call()  *****//*  Object.prototype.toString.call() 作用是:    1、获取对象的类名(对象类型)。    2、然后将[object、获取的类名]组合并返回。可应用于判断Array,Date,Function等类型的对象*/var num = new Number(1);var arr = [1,2,3];alert(Object.prototype.toString.call(num)); // [object Number]alert(Object.prototype.toString.call(arr)); // [object Array]

// 扩展示例:(apply等价于call)window.utils = {    toString: Object.prototype.toString,    isObject: function (obj) {        return this.toString.apply(obj) === ‘[object Object]‘;    },    isFunction: function (obj) {        return this.toString.apply(obj) === ‘[object Function]‘;    },    isArray: function (obj) {        return this.toString.apply(obj) === ‘[object Array]‘;    }}function A() { }window.utils.isFunction(A);        //truewindow.utils.isObject(new A());    //truewindow.utils.isArray([]);          //true

/*  jQuery等框架 就是用这个方法判断对象的类型的,因此可以把这种方法作为权威的判断方法。但是,如果重写了Object.prototype.toString方法,这时候再用来判断数据类型可能就会出错,所以,一般不要去重写Object.prototype.toString方法。*/

/********** 三:继承 **********//* JS继承和闭包一样,几乎是每个想深入学习JS的朋友都要讨论的问题,因此各种相关资料应有尽有。JS继承代码的版本非常多,但原理都是一样的,核心都是利用了prototype对象。为了和其他面向对象语言的风格相似,大多数都采用“类式”风格模拟。

继承的详细原理不再赘述,网上有许多资料介绍。这里给出一个示例:Jquery作者John Resig写的继承。(其中的详细注释是来自某个博客,不知道是谁原创,这里私自转帖出来)*/(function () {// initializing变量用来标示当前是否处于类的创建阶段,// - 在类的创建阶段是不能调用原型方法init的// - 我们曾在本系列的第三篇文章中详细阐述了这个问题// fnTest是一个正则表达式,可能的取值为(/\b_super\b/ 或 /.*/)// - 对 /xyz/.test(function() { xyz; }) 的测试是为了检测浏览器是否支持test参数为函数的情况// - 不过我对IE7.0,Chrome2.0,FF3.5进行了测试,此测试都返回true。// - 所以我想这样对fnTest赋值大部分情况下也是对的:fnTest = /\b_super\b/;var initializing = false, fnTest = /xyz/.test(function () { xyz; }) ? /\b_super\b/ : /.*/;// 基类构造函数// 这里的this是window,所以这整段代码就向外界开辟了一扇窗户 - window.Classthis.Class = function () { };// 继承方法定义Class.extend = function (prop) {    // 这个地方很是迷惑人,还记得我在本系列的第二篇文章中提到的么    // - this具体指向什么不是定义时能决定的,而是要看此函数是怎么被调用的    // - 我们已经知道extend肯定是作为方法调用的,而不是作为构造函数    // - 所以这里this指向的不是Object,而是Function(即是Class),那么this.prototype就是父类的原型对象    // - 注意:_super指向父类的原型对象,我们会在后面的代码中多次碰见这个变量    var _super = this.prototype;    // 通过将子类的原型指向父类的一个实例对象来完成继承    // - 注意:this是基类构造函数(即是Class)    initializing = true;    var prototype = new this();    initializing = false;    // 我觉得这段代码是经过作者优化过的,所以读起来非常生硬,我会在后面详解    for (var name in prop) {        prototype[name] = typeof prop[name] == "function" &&                typeof _super[name] == "function" && fnTest.test(prop[name]) ?                (function (name, fn) {                    return function () {                        var tmp = this._super; // 这里是必要的,第91行注释代码可说明之。                        this._super = _super[name];                        var ret = fn.apply(this, arguments);                        this._super = tmp;                        return ret;                    };                })(name, prop[name]) :                prop[name];    }    // 这个地方可以看出,Resig很会伪装哦    // - 使用一个同名的局部变量来覆盖全局变量,很是迷惑人    // - 如果你觉得拗口的话,完全可以使用另外一个名字,比如function F()来代替function Class()    // - 注意:这里的Class不是在最外层定义的那个基类构造函数    // 这里的Class和上边的window.Class函数不一样,这里是window.Class内部的函数局部变量    function Class() {        // 在类的实例化时,调用原型方法init        if (!initializing && this.init)            this.init.apply(this, arguments);    }    // 子类的prototype指向父类的实例(完成继承的关键)    Class.prototype = prototype;  // Class指代上边的Class,并非一开始的window.Class    // 修正constructor指向错误    // 是否可用Class.prototype.constructor = Class;来修正???    Class.constructor = Class;    // 子类自动获取extend方法,arguments.callee指向当前正在执行的函数    Class.extend = arguments.callee;    return Class;};})();    
时间: 2024-09-29 04:08:39

JavaScript必须了解的知识点总结。的相关文章

javascript面向对象系列5——知识点(原型和原型链)

基本概念 [原型链]每个构造函数都有一个对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针.那么,如果原型对象等于另一个原型的实例,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针.如果另一个原型又是另一个原型的实例,那么上述关系依然成立.如此层层递进,就构成了实例与原型的链条. [原型对象]这个对象包含可以由特定类型的所有实例共享的属性和方法.所有引用类型默认都继承了Object,而这个继承也是通过原型链实现

私人定制javascript中数组小知识点(Only For Me)

先上笑话,1.刚看到一个游泳的,想起公司组织去三亚旅游,老板跳海里,各种挣扎,捞上来老板第一句话:我记得我会游泳的啊. 2.媳妇说:老公对不起,我把你新买的自行车撞散架了! 老公:没事宝贝,你若安好,便是晴天! 媳妇说:老公你太有诗意了. 老公:滚犊子,安不好我整死你! 数组的概念 javascript数组是值得有序集合,不过它实属一个javascript对象的特殊形式,这是一个很重点的定性. 创建数组 1.var a=new Array();//等同于[] 2.var a=new Array(

javascript系列之核心知识点(一)

JavaScript. The core. 1.对象 2.原型链 3.构造函数 4.执行上下文堆栈 5.执行上下文 6.变量对象 7.活动对象 8.作用域链 9.闭包 10.this值 11.总结 这篇文章是"ECMA-262-3 in detail"系列的一个摘要和总结.每一部分包含了对应章节的连接引用,所以你可以仔细去阅读得到一个更深刻的理解.适合的读者:资深程序员,专家.我们从探讨对象的概念开始,这也是ECMAScript的奠基石. 对象 ECMAScript,一个高度抽象的面向

私人定制javascript中对象小知识点(Only For Me)

废话不多讲,先上笑话,然后再,.看懂这个的说明你的节操已经不再了. 晚饭后去理发店理发...割了吧...老板问我怎么剪,我悠悠的来一句往帅了剪...高潮往往令人想不到....旁边一在焗油烫头发的大妈说到 别这样为难老板,人家赚点钱不容易...首先如果你是高手那么请出门右转,如果你是菜鸟那么恭喜你,go on吧 全局对象在javascript程序中任何位置,都可以拈来就用的这种东西,是全局对象的属性.那么属性所在的对象也就是全局对象了.当javascript解释器启动时(或者任何Web浏览器加载新

Javascript的一些小知识点

小弟五一回家去了,本想好好的享受下五一假期,谁知悲剧的人生不需要解释.好不容易过五关斩十将,跨千山趟万水,回到家里.吃着老妈做的好菜,第二天就莫名其妙的急性肠炎,这肚子闹腾的.NND,气死哥了,早知道就不回家了.好了,废话不多说,进入主题. ================ 关于clientHeight.offsetHeight.scrollHeight window.screen.availWidth 返回当前屏幕宽度(空白空间) window.screen.availHeight 返回当前屏

私人定制javascript中函数小知识点

函数的定义 首先在javascript中,函数就是对象,程序可以随意操控它们.比如,可以给它们设置属性,甚至调用它们的方法.函数使用function关键字来定义.它既可以用在函数定义表达式,也可以用在函数声明语句中.函数声明function后面必须要更上函数名称也就是所谓的函数名称标识符.如果是函数表达式函数名称标识符可有可无.这段重点是函数是对象,所以函数表现出来的种种行为你想想成对象,那么很多疑惑可能就恍如昨日初见. 函数调用 4种方式来调用javascript函数: 1.作为函数 就是函数

总结目前为止JavaScript所学的知识点以及问题

目前为止JavaScript所学的知识点以及问题 第一章: 1.1 JavaScript的应用 1)  通过学习鼠标的事件:onclick(点击事件).onmouseover(鼠标放上).onmouseout(鼠标移走)来操作动画特效. 2)   通过学习JS语法控制页面元素CSS样式. JavaScript 能够直接写入 HTML 输出流中. JavaScript 能够对事件作出反应. JavaScript 能改变 HTML 元素的内容.样式. 1.2 JavaScript的特点 1)    

JavaScript 必会的知识点

学习Web前端中的JavaScript总结以下必会的知识点: 1. js的基本数据类型Undefined.Null.Boolean.Number.String 2. js有哪些内置对象?数据封装类对象:Object.Array.Boolean.Number 和 String其他对象:Function.Arguments.Math.Date.RegExp.Error 3. this对象的理解this总是指向函数的直接调用者(而非间接调用者):如果有new关键字,this指向new出来的那个对象:在

读《javascript语法精粹》知识点总结

昨天泡了大半天的读书馆,一口气看完了<javascript语法精粹>这本书,总体来说这本书还是写的不错,难怪那么多的推荐.<javascript语法精粹>主要是归纳与总结了javascript中的重点知识,下面我把我看玩后觉得比较重要的知识点分享出来. <javascript语言精粹>重要知识点 一.比较有意思的递归函数 1.一个有意思的递归,形成数据结构,0,1,1,2,3,5,8,13--(其实在我的<javascript常用知识点集>中也写过这个递归,