这章主要讨论闭包和原型,以及面向对象和继承。

闭包

闭包充分利用了JS里面作用域的概念,作用域的好处是内部函数可以访问定义它们的外部函数的参数和变量。使用闭包主要是为了读取函数内部的变量或者将函数内部的变量始终保持在内存中,而不让JS垃圾回收机制回收,所以使用闭包会降低系统性能的,应该避免尽量少用。

具体看下面三个例子:

var elems = document.getElementsByTagName('a');
for(var i = 0; i<elems.length; i++){
elems[i].addEventListener('click', function(e){
e.preventDefault();
console.log('i am click' +i);
}, false);
}
for(var i =0; i< elems.length;i++){
elems[i].addEventListener('click', (function(i){
return function(e) {
e.preventDefault();
console.log('i am click' + i);
}
}(i)), false);
} for(var i = 0; i < elems.length; i++){
(function(i){
elems[i].addEventListener('click', function(e){
console.log("i am click" + i);
},false)
}(i));
}

第一个例子肯定有问题,输出的都是i am click11(总共有11个超链接),关键在于触发监听的时候,获取到的i是当前循环之后的变量i,所以值是11.

第二个例子和第三个例子都是实现闭包,第三个例子比较直观易懂。这里还涉及到一个立即执行的函数概念。

立即执行函数

有两种写法,推荐第一种,如下代码所示,立即执行匿名函数,帮助封装一些方法,并且不留下任何全局变量,保护命名空间的干净,另外在闭包中也经常使用。

(function () {
alert('hello world!');
}()); (function(){
alert('hello world!');
})();

还可以像匿名函数中传递参数,如下代码所示:当然如果你把一些插件的全局变量,例如JQuery,YUI,Global传进去,那就可以实现在他们插件的基础上扩展,而且不用担心变量污染的问题。

(function(name){
alert('hello world my name is '+name);
}('tonylp'));

具体可以参考文章JavaScript学习笔记(十四) 立即执行函数

原型

原型在很多场合都会用到,尤其是面向对象方向。

对于原型(prototype)记住它既是所有function类型的对象的一个属性,这个属性本身又是一个Object对象。(片面的说又是属性又是对象)。所以我们可以给这个prototype对象添加任意的属性和方法,既然prototype是对象的“原型”,那么有该函数构造出来的对象应该都会具有这个“原型”的特性。也可以这么说,prototype提供了一群类对象共享属性和方法的机制。从这里可以看出可以使用prototype在创建新对象的同时避免复制太多的东西占用内存。我可以只赋值新的变量,而使用公共的方法。还可以通过原型继承,实现原型链。

如下代码通过原型实现基础的类,可以看到SayHello这个公用方法。

function Person(name) {
this.name = name;
} Person.prototype.SayHello = function(){
alert("Hello i am" +this.name);
}
var BillGates = new Person("Bill Gates");
var SteveJobs = new Person("Steve Jobs");
BillGates.SayHello();
SteveJobs.SayHello();
aler(BillGates.SayHello() === SteveJobs.SayHello()); // true

接下来展示一段原型链代码,object->person->employee,在SteveJobs调用SayHello的时候,首先遍历employee对象,里面没有此方法,然后通过Person.call(this,name),进入Person对象,找到该方法,然后输出,注意传入参数this和name。 其实这也是基于原型的继承,不是么

function Person(name) {
this.name = name;
} Person.prototype.SayHello = function(){
alert("Hello i am" +this.name);
} function Employee(name, salary){
Person.call(this,name);
this.salary = salary;
}
Employee.prototype.showMeTheMoney = function(){
alert(this.name + "$" + this.salary);
};
var BillGates = new Person("Bill Gates");
var SteveJobs = new Employee("Steve Jobs", 2345);
BillGates.SayHello();
SteveJobs.SayHello();
SteveJobs.showMeTheMoney();
aler(BillGates.SayHello() === SteveJobs.SayHello()); // true

都到这里了,必然能想到如果我在JS内置的对象上使用prototype,就可以扩展内置对象的方法或者属性了,是的,这条路是可行的。

昨天说到一半的创建对象,接着继续,利用原型来创建对象。

基于原型创建对象

方法1,只使用原型,但是这个方法不好,因为把所有对象的属性也挂载到原型上了,太累赘,而且没法改。

var lev=function(){

    return "啊打";
};
function Parent(){ };
Parent.prototype.name="李小龙";
Parent.prototype.age="30";
Parent.prototype.lev=lev; var x =new Parent();
alert(x.name);

方法二,和函数结合,混合模型,这个比较好,属性和方法分离

function Parent(){
this.name="李小龙";
this.age=32; };
Parent.prototype.lev=function(){ return this.name;
};; var x =new Parent(); alert(x.lev());

方法三,动态加载,其实就是混合模型,多加了一些判断,防止重复创建原型方法。

function Parent(){
this.name="李小龙";
this.age=32;
;
if(typeof Parent._lev=="undefined"){ Parent.prototype.lev=function(){ return this.name;
}
Parent._lev=true;
} };

说到原型,肯定说到遍历,然后说到hasOwnProperty()方法,用来判断是否是函数本身的方法和属性,而不是原型链上的方法和属性,很有用。看段简单的代码就可以了。

Object.prototype.bar = 1;
var foo={moo : 1}
for (var i in foo) {
if(foo.hasOwnProperty(i)) {
alert(console.log(i))
}
}//此时只会输出moo属性

JS中主要大的概念都已经说完了,还剩下一个this指针,通过this还是讲讲继承,还有AMD和CMD的一些简单介绍,JS里面的一些深坑,还有如果想继续往上深入的一些方向,在下一篇文章中结束吧。之后打算看看一些插件的源码,主要的知识点概念就那些,其实这门语言也不难的,被各大浏览器厂商坑了,还有开发这门语言的人,留下了太多的深坑,总的来说还是很有意思的,完全不同于C++,JAVA那套严谨的面向对象知识。

话说你们用webstorm卡不卡,为什么我用着这么卡呢。

以上全部都属个人思想总结,请大家转载的时候附上原创链接: http://www.cnblogs.com/tonylp

前端学习实践笔记--JavaScript深入【3】的更多相关文章

  1. 前端学习实践笔记--JavaScript深入【1】

    这一年中零零散散看过几本javascript的书,回过头看之前写过的javascript学习笔记,未免有点汗颜,突出“肤浅”二字,然越深入越觉得javascript的博大精深,有种只缘身在此山中的感觉 ...

  2. 前端学习实践笔记--JavaScript深入【2】

    趁热继续再来学习一波,接下来主要介绍函数,object,数组,面向对象,new实例化. 在介绍“对象”之前,首先得梳妆打扮一番吧,那这梳妆打扮主要有两条路线,一条是淑女范(利用函数对象化),一条是邻家 ...

  3. 每天成长一点---WEB前端学习入门笔记

    WEB前端学习入门笔记 从今天开始,本人就要学习WEB前端了. 经过老师的建议,说到他每天都会记录下来新的知识点,每天都是在围绕着这些问题来度过,很有必要每天抽出半个小时来写一个知识总结,及时对一天工 ...

  4. 前端学习 第二弹: JavaScript中的一些函数与对象(1)

    前端学习 第二弹: JavaScript中的一些函数与对象(1) 1.apply与call函数 每个函数都包含两个非继承而来的方法:apply()和call(). 他们的用途相同,都是在特定的作用域中 ...

  5. Day17-18前端学习之路——Javascript事件

    用户在某个元素上点击鼠标或悬停光标. 用户在键盘中按下某个按键. 用户调整浏览器的大小或者关闭浏览器窗口. 一个网页停止加载. 提交表单. 播放.暂停.关闭视频. 发生错误. 更多事件:https:/ ...

  6. 【InfluxDB】InfluxDB学习实践笔记

    InfluxDB是用Go编写的一个开源分布式时序.事件和指标数据库,无需外部依赖.它与Elasticsearch.Graphite等类似.比较适用于与事件紧密相关的数据,例如实时日志数据.实时监控数据 ...

  7. 《疯狂前端开发讲义jQuery+Angular+Bootstrap前端开发实践》学习笔记

    <疯狂前端开发讲义jQuery+Angular+Bootstrap前端开发实践>学习笔记 二〇一九年二月十三日星期三2时28分54秒 前提:本书适合有初步HTML.CSS.JavaScri ...

  8. vue—你必须知道的 js数据类型 前端学习 CSS 居中 事件委托和this 让js调试更简单—console AMD && CMD 模式识别课程笔记(一) web攻击 web安全之XSS JSONP && CORS css 定位 react小结

    vue—你必须知道的   目录 更多总结 猛戳这里 属性与方法 语法 计算属性 特殊属性 vue 样式绑定 vue事件处理器 表单控件绑定 父子组件通信 过渡效果 vue经验总结 javascript ...

  9. 【前端】Web前端学习笔记【2】

    [2016.02.22至今]的学习笔记. 相关博客: Web前端学习笔记[1] 1. this在 JavaScript 中主要有以下五种使用场景 在全局函数调用中,this 绑定全局对象,浏览器环境全 ...

随机推荐

  1. ASP.NET Razor——ASP.NET Razor - C#代码语法

    Razor 同时支持 C# (C sharp) 和 VB (Visual Basic). 主要的 Razor C# 语法规则 Razor 代码块包含在 @{ ... } 中 内联表达式(变量和函数)以 ...

  2. 原生select默认显示为空胡fish覅神农大丰今年圣诞节奋笔疾书发撒可交付你说的尽快发那段时间南方大厦尽可能放你的所发生的你富家大室耐腐蚀的看法呢尽快发你上课积啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊撒啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊分你束带结发你看

    下拉框默认为空: <select> <option value="" class="blank"></option> < ...

  3. subprocess模块

    subprocess的目的就是启动一个新的进程并且与之通信. subprocess模块中只定义了一个类: Popen.可以使用Popen来创建进程,并与进程进行复杂的交互.它的构造函数如下: subp ...

  4. 使用keytool 生成证书

    keytool 工具介绍 keytool 是java 用于管理密钥和证书的工具,其功能包括: 1 创建并管理密钥 2 创建并管理证书 3 作为CA 为证书授权 4 导入导出证书 keytool 采用k ...

  5. mybatis 与 日志

    如上图所示,mybatis默认支持7种日志记录的方式,也可以自己实现Log接口,然后将实现类通过LogFactory注入到日志工厂中. LogFactory是日志模块的入口,外层通过getLog获取L ...

  6. Redis执行Lua脚本的情况

    第一个测试: 往Redis里面存入1000个Hash,每个Hash里面有100个元素(Key 0-99,值是Key^2). PHP代码,执行33s左右 <?php $redis = new Re ...

  7. STM32固件库3.5+uCOS2.86移植(转自暴走的工程师)

    考了很多移植的资料和代码,终于移植好了...应该是完美移植吧~~哈哈哈~~ 编译环境是IAR 工程适用于STM32F10X大容量产品,如果不是,请自行修改启动文件和工程配置 编译器优化等级最高...这 ...

  8. C#动态webservice调用接口 (JAVA,C#)

    C#动态webservice调用接口 using System; using System.Collections; using System.IO; using System.Net; using ...

  9. meta 标签 详细说明

    meta 标签可提供页面元素信息, 使用键值对的定义方式,可以记录网页上的主要信息,也可以自定义键值对 属性 content(必须),name,http-equiv,scheme,lang 常用 me ...

  10. SQL分页查询

    假如tb_customer表中的数据量非常大,在显示时要分页显示而且每页只显示10条信息.为了效果我们取第三页的数据. 方法一:遍历两次表,取不同的数据. select top 10 * from t ...