javascript基础的一些总结
一 闭包
各种专业文献上的"闭包"(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。
由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
function f1(){
var n=999;
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
上一段代码中的f2函数,就是闭包。
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中:
function f1(){
var n=999;
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000
二 JS中函数声明与函数表达式的不同
Js中的函数声明是指下面的形式:function functionName(){}
这样的方式来声明一个函数,而函数表达式则是类似表达式那样来声明一个函数,如:var functionName = function(){}
看到这两一种写法时会产生疑惑,这两种写法差不多,在应用中貌似也都是可行的,那他们有什么差别呢?
事实上,js的解析器对函数声明与函数表达式并不是一视同仁地对待的。对于函数声明,js解析器会优先读取,
确保在所有代码执行之前声明已经被解析,而函数表达式,如同定义其它基本类型的变量一样,
只在执行到某一句时也会对其进行解析,所以在实际中,它们还是会有差异的,具体表现在,
当使用函数声明的形式来定义函数时,可将调用方式在函数声明之后,而后者,这样做会报错。
三 数值
NaN“非数值”,具有毒性,bug。typeof类型是number(这是typeof操作符最奇怪的行为之一)。
.1+.2 结果为0.30000000000000004。
利用Math.round()方法获得两位数的精度。
Math.round((.1+0.2)*100)/100 结果为0.3;
"sdxf".indexOf("x")在sdxf中出现的位置:3
"sdxf".charAt(4)在sdxf中的第4位字母是:f
类型比较:1=="1"返回true,1==="1"返回false。
变量:i=0,隐式声明,隐式声明的变量总是具有全局作用域的,即使该变量是在某个函数函数体中声明。(建议用var关键字声明,而且建议在作用域的顶部声明)
var i=0;显式声明。
var i;未初始化,包含特定的值undefined。
四 对象
对象:对象是属性的集合,每一个属性具有一个名称和一个值。属性可以包含除undefined外的任何类型,在创建对象之后可以对属性赋值。
实例化对象,第一种方法使用new关键字:
var myObject=new Object();
new 关键字将调用构造函数,或者更通用的说法是构造器。构造器将初始化新创建的对象。
构造函数:
function cName(name){
alert(name);
}
var ccname=new cName("构造函数");
实例化对象,第二种方法使用字面量(这种方式创建对象更像其他语言中的散列【hash】或关联数组):
var myObject={};
var domArr={
"name":"构造函数2",
"age":myObject
}
var nm=domArr["name"];//可以用.,如下
var ag=domArr.age;
alert(nm);
alert(ag);
因为属性也可以是对象,可以在任意层上嵌套对象:
var tem={ "name":{"bbo":{"uu":"h", "dd":"i"}}};
alert(tem.name.bbo.uu) 结果为 h。
javascript是一种动态语言,因此要更新一个属性,只需要重新对属性值赋值即可。要移除一个属性,只需使用delete操作符,删除不存在的属性不存在危险。
javascript使用原型继承,对象直接从其他对象继承,从而创建新的对象。简而言之,对象继承另外一个对象中的属性。因为javascript中没有类。
例如,人,javascript中是没有人这个类的,而是张三继承了李四这个人的特征【属性】(眼睛,鼻子,年龄等),形成了新的对象“张三”。
在创建新对象时,注意对象的初始化:
var object1=object2={}//引用的是同一个对象。
var object1={},object2={}//引用的不是同一个对象。
五 函数、闭包、变量
我们认为尽量避免使用全局变量,但有些情况是必须的,所以我们会采取一些办法避免扰乱全局名称空间。
一种办法是使用单个全局变量作为顶层对象,包含程序或框架中的所有方法和属性。安装惯例,命名空间都采用全部字母大写,但值得注意的是常量也用大写格式。
BBNN_PPO={};
BBNN_PPO.Clem={
"name":"agele",
"age":"5"
}
BBNN_PPO.Dem={
"name":"Cdiny",
"age":"4.5"
}
另外一种是采用闭包:
函数:函数是一个代码块,他封装了一系列的javascript语句。函数可以接收参数,也可以返回值。
与c#和java不同,javascript中的函数是第一类(first-class)的对象。
返回值,接参数:
function calc(x){
return x*10;
}
alert(calc(30));
结果300。
如果函数没有返回一个特定的值,则它将返回一个undefined的值:
var x=2;
function calc()
{
x=x*10;
}
alert(x);//结果为20
alert(calc());//结果为 undefined
函数赋值给一个变量:
var calc=function(x)
{
return x*2;
}
alert(calc(5));//结果为 10。
给函数名使用圆括号,将执行该函数并返回函数的值,而不是返回对该函数的引用。
将函数作为参数传递给其他函数:
function demo(fn){
alert("这是接收来的:"+fn());
}
demo(function(){ return "大哥哥"});
//结果为“这是接收来的:大哥哥”
二式:
function demo(fn)
{
alert("这是接收来的:"+fn());
}
function calc()
{
return 2*3;
}
demo(calc);
//结果为“这是接收来的:6”
匿名函数:一个特别重要的变体就是立即调用函数表达式,或称为自执行匿名函数。
这一模式的本质是将一个函数表达式包装在一对括号中,然后立即调用该函数。
这一技巧非常简单,将函数表达式包装在一对圆括号中,将迫使javascript引擎将function(){}块识别为一个函数表达式,而不是一个函数语句的开始。
(function(x,y){
alert(x+y);
})(5,6);//结果为 11,最后这圆括号(5,6),可以写在前面个圆括号内
由于这一的函数表达式将被立即调用,因此该模式用于确保代码块的“执行上下文”按照预的期效果执行,这是这种模式最重要的用途之一。
通过将参数传入函数,在执行时就可以捕获函数所创建的闭包中的变量。
闭包就是这样一个函数:它处在一个函数体中,并应用了函数体当前“执行上下文”中的变量。
闭包的应用,及函数中将另外一个函数作为返回值:
var x=24;
alert(x);结果为:24
var message=(function(x){
return function(){//函数中另外一个函数作为返回值
alert("闭包中的x是:"+x);//结果是:闭包中的x是:24
}
})(x);
message();//没结果
x=12;
alert(x);//结果为:12
message();//结果是:"闭包中的x是:24",无论外部作用域x的值发生什么变化,闭包将记住函数执行时变量x的值。
“执行上下文”:它是一种对象,代码在“执行上下文”环境中执行。可以通过this关键字来访问“执行上下文”,this关键字是对当前“执行上下文”对象的引用。
若代码不存在于用户自定义对象或函数中,那么它将属于“全局上下文”。
在javascript中,没有定义具体“上下文”的函数,将把它们的this关键词的值绑定为undefined值。
alert(this);//[object DOMWindow]
eval函数setTimeout函数具有自己独立的“执行上下文”。
在开始执行一个函数或方法时,javascript创建了一个新的“执行上下文”并进入该函数的“执行上下文”,当函数执行完毕并返回时,控制权将交给原来的“执行上下文”。
在创建闭包时当前“上下文”将保留下来,否则当前“上下文”将被当着垃圾收集。
作用域和闭包:
讨论作用域时,考虑定义变量的位置和变量的生存期非常重要。作用域是指在什么地方可以使用该变量。
在javascript中,作用域维持在函数级别,而不是块级别。因此,参数以及使用var关键字定义的变量,仅在当前函数中可见。
嵌套函数:除了不能访问this关键字和参数之外,嵌套函数可以访问外部函数中定义的变量。这一机制是通过闭包来实现的,它指的是:即使在外部函数解释执行之后,内部嵌套函数继续保持它对外部函数的引用。闭包还有助于简绍名称空间的冲突。
每次调用一个包裹(enclosed)的函数时,虽然函数的代码并每月改变,但是javascript将为每一次调用创建一个新的作用域。
function getCom(value){
return function(value){
return value;
}
}
var a=getCom(),b=getCom(),c=getCom();
alert(a(0));//结果为 0 ,每一次调用都创建新的作用域
alert(b(1));//结果为 1
alert(c(2));//结果为 2
alert(a===b);//false;
});
当定义一个独立函数(没有绑定任何对象)时,this关键字绑定与全局名称空间。
作为一个最直接的结果,当在一个方法内创建一个函数时,内部函数的关键字this将绑定与全局名称空间,而不是绑定该方法。
为了解决这个问题,可以将包裹方法的this关键字简单地赋值给一个名为that的中间变量。
var obj={};
obj.mathod=function(){
var that=this;
this.counter=0;
var count=function(){
that.counter+=1;
alert(that.counter);//上层函数定义的值传不进来
}
count();//结果为 1;
count();//结果为 2;
alert(this.counter);//当没有调用到内部函数时,值为0;现在值为2
}
obj.mathod();
(个人理解:一个小偷,一个叫花子,都想吃到食物(内心世界=内部函数),小偷进入主人家(家=外部函数),但却找不到食物(食物=外部函数变量),叫花子侧在家门口(外部函数之外)乞讨,却得到了食物(函数变量),所以小偷想获得食物必须迂回到外部方能求得食物)
在javascript中并没有官方的访问级别语法,javascript没有类似于java语言中的private或protected这样的访问级别关键字。默认情况下,对象中的成员都是共有和可访问的。但在javascript中可以实现与私有或公有属性类似的访问级别效果。要实现私有方法或属性,请使用闭包:
function reTun(){
var chaer="狠狠不如意";//私有
this.oo=function(){//闭包
return chaer;//公有
}
}
var dem=new reTun();
alert(dem.chaer);//undefined
alert(dem.oo());//狠狠不如意
this.oo()是函数reTun的专有方法,它可以访问reTun中的私有成员。另外chaer变量是“私有”的,他的值只能通过专有方法进行访问
使用模块:与私有和专有访问级别类似,在javascript中没有内置的包语法。模块模式是一种常用的编码模式
TTMMOON={};// 创建名称空间
TTMMOON.teme=(function(){//函数表达式
var destion="",molde="",fulle="";//私有成员
//公有访问方法
return{
//设置器
setDestion:function(dest){
this.destion=dest;
},
setModl:function(mold){
this.molde=mold;
},
setFulle:function(full){
this.fulle=full;
},
//访问器
getDestion:function(){
return this.destion;
},
getModl:function(){
return this.molde;
},
getFulle:function(){
return this.fulle;
},
//其他成员
toString:function(){
alert(this.getModl()+"-嗨,中国"+this.getFulle()+"-谢谢您们!"+this.getDestion());
}
//在这里执行初始化过程
}
}());
var myTimeus=TTMMOON.teme;
myTimeus.setModl("我叫joy,");
myTimeus.setFulle(",我很开心");
myTimeus.setDestion("我会回来的。");
myTimeus.toString();
});
六、数据类型、javascript实践
扩展类型:
javascript支持将方法和其他属性绑定到内置类型,比如字符串、数值和数组类型。与其他任何对象类似,String对象也具有prototype属性。开发人员可以为String对象扩充一些便利的方法。例如,String没有将字符串false或true转换为布尔值的方法。
可以用下面的代码为String对象添加该功能:
String.ptrototype.boolean=function()
{
return "true"==this;
};
var t='true'.boolean();
var f='false'.boolean();
alert(t);//ture
alert(f);//false
简化二:
Function.prototype.mathod=function(name,func)
{
this.prototype[name]=func;
return false;
}
String.mathod("boolean",function(){
return "true"==this;
})
"true".boolean();//true
javascript的最佳实践:
1、使用parseInt()函数将字符串转换为整数,但确保总是指定基数。更好的办法是使用一元操作符(+)将字符串转化为数值:
Good:parseInt("010",10);//转化为十进制
Better:+"010";//高效
2、是用等同(===)操作符来比较两个值,避免意料之外的类型转换。
类型比较:1=="1"返回true,1==="1"返回false。
3、在定义对象字面量时,在最后一个值的结尾不要使用逗号:
var obj={
name : "any",
age : "20"
}
4、不要使用with语句。
5、在循环中创建函数应该谨慎小心,这种方式非常低效。
6、eval()函数可以接受一个字符串,并将其视为javascript代码执行。应该限制eval()函数的使用,它很容易在代码中引入各种各样严重的安全问题。
7、使用分号作为语句的结尾,当精简代码时特别有用。
8、应该避免使用全局变量。应该总是使用var关键字来声明变量。将代码包裹在匿名函数中,避免命名冲突,请使用模块来组织代码。
9、对函数名使用首字母大写表示该函数将作为new操作符的构造函数,但请不要对其他任何函数的函数名使用首字母大写。
javascript基础的一些总结的更多相关文章
- JavaScript基础
JavaScript基础 JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处 ...
- 一步步学习javascript基础篇(0):开篇索引
索引: 一步步学习javascript基础篇(1):基本概念 一步步学习javascript基础篇(2):作用域和作用域链 一步步学习javascript基础篇(3):Object.Function等 ...
- 前端之JavaScript基础
前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript历史 1992年Nombas开发出C ...
- 一步步学习javascript基础篇(3):Object、Function等引用类型
我们在<一步步学习javascript基础篇(1):基本概念>中简单的介绍了五种基本数据类型Undefined.Null.Boolean.Number和String.今天我们主要介绍下复杂 ...
- Javascript基础回顾 之(三) 面向对象
本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...
- Javascript基础回顾 之(二) 作用域
本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...
- Javascript基础回顾 之(一) 类型
本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...
- JavaScript 基础回顾——对象
JavaScript是基于对象的解释性语言,全部数据都是对象.在 JavaScript 中并没有 class 的概念,但是可以通过对象和类的模拟来实现面向对象编程. 1.对象 在JavaScript中 ...
- javascript基础01
javascript基础01 Javascript能做些什么? 给予页面灵魂,让页面可以动起来,包括动态的数据,动态的标签,动态的样式等等. 如实现到轮播图.拖拽.放大镜等,而动态的数据就好比不像没有 ...
- javascript基础02
javascript基础02 1.数据类型 数据类型的描述在上篇的扩展中有写到链接 由于ECMAScript数据类型具有动态性,因此的确没有再定义其他数据类型的必要.这句话很重要. 如果以后再数据类型 ...
随机推荐
- Mac查看Python安装路径和版本
目录 #查看当前所有Python版本路径 appledeMBP:~ apple$ which python2.7 /usr/local/bin/python2.7 appledeMBP:~ apple ...
- 部署zabbix3.2.7,升级到3.4、proxy部署
一.Server安装 可以使用mysql.percona.mariadb等,本例使用mariadb.由于是事后整理,只截取部分命令. #yum install mariadb-server maria ...
- apache服务器配置防盗链(centos7)
<Directory /data/wwwroot/xwl.com> SetEnvIfNoCase Referer "^$" local_ref SetEnvIfNoCa ...
- oracle函数 to_single_byte(c1)
[功能]将字符串中的全角转化为半角 [参数]c1,字符型 [返回]字符串 [示例] SQL> select to_multi_byte('高A') text from dual; test -- ...
- ros自定义消息
ros自定义消息可以根据自身项目需求定义和封装想要的数据类型和数据结构.具体可以参考维基百科关于ros自定义消息部分 这里我只是记录自定义消息的要点部分: 1.首先要在工作空间下功能包中创建一个msg ...
- 13-2 jquery介绍
1 什么是 jQuery jQuery 是 js 的一个库,封装了我们开发过程中常用的一些功能,方便我们调用,提高开发效率. js库是把我们常用的功能放到一个单独的文件中,我们用的时候,直接引用到页面 ...
- FastReport模板设计和调用
FastReport是功能齐全的报表控件,使开发者可以快速并高效地为·NET/VCL/COM/ActiveX应用程序添加报表支持.最近一个项目就涉及到了FastReport报表的应用.这里简单记录下( ...
- 2019-8-31-dotnet-使用-MessagePack-序列化对象
title author date CreateTime categories dotnet 使用 MessagePack 序列化对象 lindexi 2019-08-31 16:55:58 +080 ...
- Android教程-02 在程序中输出Log
视频教程,建议采用超清模式观看 在Android中一般都用Log输出日志,常见的有5个不同的级别 Log.v() Log.d() Log.i() Log.w() Log.e() 当然很多程序员还比较习 ...
- Android Studio(十):添加assets目录
Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...