javascript 特性

作用域: javascript的作用域称为静态作用域,在定义语法上就能确认了,而不是运行时。

 if (true)
{
  var i = ‘moersing‘
}
console.log(i); //可以访问。

与C#,vb,java等语言不同,javascript没有所谓块级作用域概念,准确的说,就花括号之内定义的变量可以被外面访问到,但是,函数除外,因为函数本身是一个作用域。

另一个例子:

var s= ‘moersing‘;
var f= function () {
  console.log(s); //这里输出的是undefined
  var  s=‘lingfo‘;
}
f();

解释下为什么会这样,原因是javascript作用域搜索的问题,在调用函数f的时候,f作用域(函数都有一个局部作用域),会初始化所有局部变量(只是初始化),于是,console.log()函数访问s的时候,s并没有被赋值,也就相当于 var s而已,所以输出undefind。

闭包特性:

function f ()
{
   var count=0;
   var get =function(){
       count ++;
       return count;
    }
return get;
}
var  getCount = f();
console.log(getCount()); //1
console.log(getCount());//2

通常,在不使用闭包的情况下,让一个变量递增的办法就是在外层定义一个变量,然后调用方法让其自增。

但是这样做的不好之处在于,别的地方也能访问这个变量,有时会很糟糕。

上面的例子就是一个闭包,在函数f执行完毕之后,返回一个get函数,这时候你可能会认为这个函数里面的count变量已经被销毁,

因为f已经超出作用域了,但实际上不是这样,在返回的get函数中,仍让保留着f的活动对象,当然也包括在其中定义的count变量,

所以,每一次调用get这个函数的时候,应用的都是count这个变量,也就实现了内部自增,除非通过f函数,否则无法访问这个count。

有些网友时常问,我想根据点击的按钮的位置(下标)来执行相应的操作,但是最后总是无法获取到下标,那是因为,在for循环中绑定的下标是是会变化的,当for循环执行完成后,下标的值总是等于 i+1。如:

<div>0</div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>

var allDiv = document.querySelectorAll(‘div‘);
for(var i=0;i<allDiv.length;i++)
{
    allDiv[i].onclick=function(){     alert(this.nodeName+i);    }
}在这里,无论单击那个DIV,都会返回  DIV9,原因是,for循环最后一次++是等于9,而9 < allDiv.length =false,所以,循环退出,但是在每个div里面绑定事件是显示i的值,所以一直都是9.

利用javascript提供的闭包特性可以解决这个问题。

<div>0</div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>

var allDiv = document.querySelectorAll(‘div‘);
for(var i=0;i<allDiv.length;i++)
{
   (function(i){
        allDiv[i].onclick=function(){
        alert(this.nodeName+i);
    }
    })(i);
}

对于闭包特性,通俗来讲,就是嵌套的函数包含了父函数的作用域和本身的作用,这个新的作用域称为闭包特性,但是要记住,当父函数返回之后,作用域就被销毁,但是其活动对象还是会保留在嵌套的函数之中。

另外一个就是:慎用闭包,特别是在操作有关DOM处理的时候,如果一不小心,会造成内存泄露。

this对象:

var  m = {
name:‘moersing‘,
func:function(console.log(this.name))
}
var t = {
name:‘linfo‘,
}
m.func(); // moersing
t.func= m.func;
t.func();//linfo;

在m的func函数中,引用了this(上下文对象)即被调用的函数所处的环境(作用域),而下面的t.func指向了m.func,那么,实际上就相当于  t.func={console.log(this.name)},接下来就浅显易懂了,调用t的func,那么,this这个上下文对象就相当于t,那么也就是t.name。所以结果输出了linfo。

call和apply:

call和apply的执行机制是一样的,他可以设置函数的执行环境,也就是说可以改变一个函数所处的位置(非物理),别忘了,函数的上下文对象(this)也是根据函数所处的位置变换的。

首先,看看call:

 var m = {
    name:‘moersing‘,
    age:18,
    print:function(){  console.log(this.name+this.age)  }
}
   var t = {name:‘linfo‘,age:20}
 m.print.call(t); //info 20

这里,在运行时,将print函数的执行环境改变成了t(call函数第一个参数是一个对象,就是上下文对象),那么,this.name

就相当于 t.name,同理,age也是一样的。

apply与call一样,只不过他可以传递数组 fun.call(obj,[1,2,3,........]);

__proto__和prototype和constructor:

__proto__:指向对象的原型。
prototype:指向了构造函数的原型对象。
constructor:对象(包括原型)有一个constructor属性,这个属性指向了其所在的函数。

注:对象和实例是相同的概念。

也就是说,prototype和constructor是间接互相引用的。

值得区分的就是 __proto__和prototype:

这两个对于有经验的人也许会有点困惑,__proto__是存在于实例与构造函数之间的,而prototype是存在于构造函数和原型之间的。

这也就是为什么,构造函数有prototype和__proto__,而实例只有__proto__。别忘了,构造函数也是对象。

很多人误认为,构造函数的__proto__和prototype是指向相同的原型,实际上不是的,看一个例子:

 function c (){ };
 alert(c.__proto__); // function empty()
 alert(c.prototype); // c
从上面可以看出两者之间的不同。
 var cc= new c();
 alert(cc.__proto__==c.prototype); //true

如果使用c作为构造函数,那么cc实例的__proto__就和c.prototype一致了。

下面是一些例子:

console.log(obj.__proto__ === Object.prototype) // true
console.log(arr.__proto__ === Array.prototype)  // true
console.log(reg.__proto__ === RegExp.prototype) // true
console.log(date.__proto__ === Date.prototype)  // true
console.log(err.__proto__ === Error.prototype)  // true

从上面可以看出,对象实例的__proto__都指向了构造该对象的原型对象。

例如: Object 构造了obj (var o={})   那么这个对象的__proto__就指向了 Object.prototype。

另外,Object.prototype是最高层的原型,根据原型链搜索的概念  任何对象  instanceof  Object 都是true。

总结:对于__proto__和prototype的概念,千万要记住的就是,两者之间没有可比性,一个是存在于实例和原型之间,一个是存在于构造函数和原型之间。

本人纯属菜鸟,如果有什么不对的地方,还请指正,原创文章,转载请注明地址。QQ:1261870167  

时间: 2024-09-29 19:43:00

javascript 特性的相关文章

7 个 JavaScript “特性”

原文链接:http://blog.scottlogic.com/2015/07/02/surprising-things-about-js.html more 从任何一个代码块中 break 你应该已经知道你可以从任意循环中 break 和 continue —— 这是一个相当标准的程序设计语言结构.但你可能没有意识到,你可以给循环添加一个 label ,然后跳出任意层循环: outer: for(var i = 0; i < 4; i++) { while(true) { continue o

深入理解JavaScript特性

最近在读<JavaScript高级程序设计>这一本书,里面提到了JavaScript的特征,倍感兴趣,于是结合自己的认识,在这里进行一下总结. 1.JavaScript的垃圾回收机制 javaScript中的5种数据类型存放在栈中(Undefined.Null.Boolean.Number.String),非基本数据类型存放在堆中,占用内存,堆不会被程序自动释放. 一张图看懂JS中数据类型的存放位置:基本数据类型存放在栈中,非基本数据类型存放在堆中(对象),变量obi1在栈中存储的只是堆中对象

JavaScript权威指南第13章 web浏览器中的javascript

13.1 客户端javascript window对象是所有的客户端javascript特性和api的主要接入点.表示浏览器的一个窗口,可以通过window对象来引用它. window 的方法 alert() prompt() confirm() 13.2 在html里嵌入javascript 4种方法: 内联:放置在<script></script>标签之中 外部引入:<script src="   "></script> html程序

JavaScript资源大全

目录 前端MVC 框架和库 包管理器 加载器 打包工具 测试框架 框架 断言 覆盖率 运行器 QA 工具 基于 Node 的 CMS 框架 模板引擎 数据可视化 编辑器 UI 输入 日历 选择 文件上传 其它 提示 模态框和弹出框 滚动 菜单 表格/栅格 框架 手势 地图 视频/音频 动画 图片处理 ECMAScript 6 软件开发工具包(SDK) 利器 前端MVC 框架和库 angular.js:为网络应用增强 HTML.官网 aurelia:一个适用于移动设备.桌面电脑和 web 的客户端

JavaScript BOM

JavaScript特性: 交互性 安全性(不可以直接访问本地硬盘) 跨平台性(只要是可以解析js的浏览器都可以执行,和平台无关) JavaScript三大核心: 1)核心(ECMAScript):描述了JS的语法和基本对象. 2)文档对象模型 ☆(DOM):处理网页内容的方法和接口 3)浏览器对象模型(BOM):与浏览器交互的方法和接口 BOM对象: 1. DOM 是 W3C 的标准: [所有浏览器公共遵守的标准] 2. BOM 是 各个浏览器厂商根据 DOM 在各自浏览器上的实现;[表现为不

JavaScript权威设计--Window对象(简要学习笔记十三)

1.Window对象是所有客户端JavaScript特性和API的主要接入点. Window对象中的一个重要属性是document,它引用Document对象. JavaScript程序可以通过Document对象和它包含的Element对象遍历和管理文档. 2.URL中的JavaScript 在URL后面跟一个JavaScript:协议限定符.里面的代码会作为JavaScript代码进行运行,需用分号分割. 如: <a href="javascript:alert('OK!')"

悟透JavaScript

From: 李战,http://www.cnblogs.com/leadzen/archive/2008/02/25/1073404.html 引子 编程世界里只存在两种基本元素,一个是数据,一个是代码.编程世界就是在数据和代码千丝万缕的纠缠中呈现出无限的生机和活力. 数据天生就是文静的,总想保持自己固有的本色:而代码却天生活泼,总想改变这个世界.    你看,数据代码间的关系与物质能量间的关系有着惊人的相似.数据也是有惯性的,如果没有代码来施加外力,她总保持自己原来的状态.而代码就象能量,他存

第十章:Javascript子集和扩展

本章讨论javascript的集和超集,其中子集的定义大部分处于安全考虑.只有使用这门语言的一个安全的子集编写脚本,才能让代码执行的更安全.更稳定.ECMScript3标准是1999年版本的,10年后,ECMAScript5规范的更新,由于ECMAScript标准规范是允许对其做任何扩充的,伴随着Mozilla项目的改进,Firefox1.0.1.5.2.3.和3.5版本中分别发布了javascript1.5.1.6.1.7.1.8.1.81版本,这些javascript的扩展版本已经融入到EC

JavaScript 资源大全中文版

包管理器 管理着 javascript 库,并提供读取和打包它们的工具. npm:npm 是 javascript 的包管理器.官网 Bower:一个 web 应用的包管理器.官网 component:能构建更好 web 应用的客户端包管理器.官网 spm:全新的静态包管理器.官网 jam:一个专注于浏览器端和兼容 RequireJS 的包管理器.官网 jspm:流畅的浏览器包管理器.官网 Ender:没有库文件的程序库.官网 volo:以项目模板.添加依赖项与自动化生成的方式创建前端项目.官网