js笔记
犀牛书;微信公共号:前端大全;js1k;
javascript:js,运行于js解析器客户端的脚本解释引擎中
脚本语言:只有在运行时才会被编译或解释的语言
解释型:执行时才检查语法错误;遇到错误才停止运行
(编译型:运行前会检查语法结构,错误则不运行,自动优化程序代码)
运行环境:
1.独立安装的js解析器(NodeJS)
2.嵌入在浏览器内核中的js解析器
js特点:
1.任何文本编辑工具都可编辑
2.无需编译,js的引擎负责执行
3.弱类型语言:数据决定变量数据类型,可先后保存不同类型数据(强类型语言由数据类型决定数据)
4.面向对象(oo)
js用途:
客户端js (1)、客户端数据计算 (2)、表单验证 (3)、浏览器事件的触发和处理
(4)、网页特效/动效制作 (5)、异步数据提交(Ajax)
服务器端js (1)、分布式运算 (2)、实时服务器 (3)、窗口应用 (4)、网络应用
使用js:
浏览器内核
作用:页面的渲染
组成:内容排版引擎:解析HTML/CSS
脚本解释引擎:解析JS
浏览器 内核 排版引擎 脚本引擎
IE Trident - Chakra
Firefox Gecko - 猴子系列
Safari Webkit Webcore Nitro
Chrome Webkit Webcore V8
Opera Presto - Carakan
Opera(2013)Webkit Webcore V8
搭建JS运行环境:
1.独立的js解释器:Node.JS
cmd-node.exe-console.log("...");
作用:向控制台中打印输出一句话。
2.浏览器内嵌的js引擎
(1)直接在浏览器的控制台(console)输入脚本并执行
(2)JS脚本嵌入在HTML页面中执行
1)通过html元素事件完成脚本执行
2)通过<script>元素 执行JS脚本:可放在head中或body中
<script language="JavaScript" type="text/JavaScript"></script>
3)外部调用(*.js):<script src="*.js"></script>:外部调用script元素中不能出现js代码
4)使用js协议:
<a href="JavaScript:alert('Hello World!!!')">请单击</a>
<a href="#" onclick="alert('Hello World!!!')">请单击</a>
<a href="JavaScript://" onclick="alert('Hello World!!!')">请单击</a>
js调试:
IE:状态栏/IE8开始提供的开发工具
firefox/chrome:控制台,F12
1. 多行编写: shift+enter
2. 切换已经执行过的旧代码:: ↑ ↓
3. 清屏: 左上角圆形叉 clear
4. 控制台可直接输出表达式的结果
5. 字体大小: ctrl+鼠标滚轮
6. 窗口大小: 右上角: Dock图标
原生js组成:
核心ECMAScript:js语言核心语法标准
文档对象模型DOM:操作网页内容的API,Document Object Model,广泛支持
浏览器对象模型BOM:操作浏览器窗口的API,Browser Object Model,W3C组织定义了相关的操作规范和标准
js不存在块级作用域,循环体内部定义的变量可在外部访问到,只支持函数作用域,可把循环体放到函数中实现闭包
变量:
命名:字母($_不推荐)开头,其他可以是$_数字
var x=new String; 可用new显示声明类型
即使未声明也可赋值,JS自动创建该变量
连等a=b=c=3
声明提前hoist:执行js前,引擎会提前集中到程序的顶部创建所有var声明的变量和function声明的函数,变量的赋值留在原地,随脚本解释执行
调用函数时,优先使用局部变量;没有时去全局找;如果全局也没有则报错ReferenceError
函数的参数变量也是局部变量,只不过不用var创建
全局变量可在整个脚本中被使用,可在不同的窗口中相互引用(指定窗口名)
常量:
const PI = 3.14;习惯上常量名使用纯大写,常量的值不能被改变
强制修改,程序不会报错;但是也不会被修改成功,只不过是新建了个常量
命名:匈牙利命名法;驼峰命名法:第一个单词小写,其余每个单词首字符大写;下划线命名法
存/取值:var a=b; a是存值操作,b是取值操作,赋值符号左边只能是变量
垃圾回收:
释放不再被任何变量引用的对象
垃圾回收器: 专门记录对象的引用次数,并回收不再被引用的对象的程序。
垃圾回收器和主程序并行在后台执行
垃圾回收器会为每个对象创建一个引用计数器(counter)
只要多一个变量引用对象,counter就会被+1
只要一个变量释放了对对象的引用,counter就会被-1
不再有任何变量引用该对象时(counter=0),对象被垃圾回收器释放。
null专用于主动释放一个对象;在使用完一个较大的对象后主动释放
原始数据类型:值直接保存在变量本地的数据类型
number类型:
整数4字节(32位),浮点数8字节(64位)
八进制:0;十进制:0x
js只有一个单一的数字类型,内部被表示为64位浮点数,∴1===1.0
isFinite(变量) 函数可以检测数值是否在范围内true
n.toFixed(2) 将数字按2位小数四舍五入
NaN是number类型,代表所有无效数字的值,not a number;
NaN不等于一切,普通关系运算无法判断且参与任何运算无法计算
String类型:
用" "或' '括起来;网页中接收用户的数据全都是string类型
字符串长度:length属性;
字符串都为true
字符按unicode编码存储
一个英文字母/数字/标点=1byte字节;一个汉字=2字节
一个字符串,一旦创建,无法局部修改
toUpperCase()方法:将字符串转换为大写
indexOf() 方法:定位字符串中某一个指定的字符首次出现的位置
match() 方法:查找字符串中特定的字符,有则返回该字符,无返回null
replace(/a/,"b"))方法:替换a为b
转义字符/字符字面量:
\n换行\u000A \t制表 \b退格 \r返回 \f进页 \\反斜 \'单引号
\"双引号 \xnn十六进制字符 \unnn十六进制的Unicode字符
boolean类型:true==1;false==0;
undefined:变量不含有值,未初始化自动取值undefined
null:空,用于手动清空值
隐式转换:
默认转为数字类型Number计算
任何数据与string相加结果为string
typeof 变量/(变量) typeof是操作符,检查变量/字符字面量数据类型,
返回string/number/boolean/object/function/undefined
x instanceof Object; 检查x是否是Object对象类型
显示转换:
x.toString() 转换成string类型,不能转null/undefined(原因null和undefined表什么都没有,不能加.调用函数)
String(x) 万能;原理:function String(x){ if(x===undefined){return "undefined";}
Else if(x===null ){ return "null";}else{ return x.toString();}}
Number(x) 非字符串to number; ""/null/[]返回0;undefined返回NaN;true/false返回1/0
parseInt(str) 字符串转换成整数,
跳过开头空字符,碰到第一个非数字字符则退出;
第一个就是非数字字符返回NaN;
固定套路:去掉字符串中数字之后的单位
parseFloat() 转换成小数;碰到第一个非数字字符停止转换;第一个就是非数字字符返回NaN
Boolean(x) 0,undefined,null,NaN,""为false,其余都转为true
x.charCodeAt(); 字符转ascii码;\u4e00~\u9fa5汉字;A~Z&&a~z字母;
String.fromCharCode(x); ascii码转字符
有符号整数:最后一位0表正,1表负
负数以二进制补码存储:绝对值反码(1/0互换)——反码+1
①算术运算符:+-*/%
+:可以进行加法运算或字符串连接,加法运算需确保两个运算数是数字
/:可能产生一个浮点数
%:判断奇偶性,判断x 数字的倍数,获取某数字的最后几位;限制一个运算结果不能超过指定上限
②关系/比较运算符:>, <,>= ,<= ,==, !=
==相等/!=不相等:默认都转为数字再比较大小
===全等/!==不全等:首先比较类型再比值
引用该类型的对象/null,则不隐式转换而比较地址值 []==[]; 返回false;比较的是地址; []表创建数组
参与比较的两个值都是字符串,不再转数字,而是逐位PK每个字符的unicode号
undefined==null: 会将undefined自动转为null
③逻辑运算符:
!非
&& 且:第一个值为假则结果为假;
条件&&赋值; 可作为单独执行语句或条件判断
|| 或:第一个值为真则结果为真;
var max=max||pre.max||500; ||条件 变量必须先声明
function(o,p){p=p||[];}如果参数p没有传入则创建一个空数组并赋值给p
短路:如果前一个条件得到结果则其余条件不执行
④位运算符:简化代码量
左移 m<<n :m* 2的n次方 m*Math.pow(2,n)
右移 m>>n :m/ 2的n次方 m/Math.pow(2,n)
无符号右移>>>:负数会变成非常大的正数,正数正常
按位非 ~ :1/0互换(反码) 操作数的负值-1 x=~y等价于x=-y-1
按位与 & :只有1&1=1
按位或 | :只有0|0=0
按位异或 ^ :相同返回0;不同返回1
⑤赋值运算 =
⑥字符连接运算 +
⑦条件运算符:变量=(条件)?值1:值2; 满足条件赋值值1
⑧特殊运算符 typeof i nstanceof void delete
运算符优先级
. [] () 属性存取及函数调用
delete new typeof + - ! ~ ++ -- 一元运算符
* / % 乘,除,取模
+ - 加法/连接,减法
<< >> >>> 位位移
>= <= > < 不等式运算符
=== !== 等式运算符
& ^ (xor)| 位逻辑
&& 逻辑与
|| 逻辑或
? : 三元
= 赋值
n+=btn.innerHTML=="+"?1:n>1?-1:0; 如果btn是+,就n+1,否则,如果n>1,才n-1,否则n继续等于1
语句/结构:
for(声明(赋值);条件;...)声明(赋值)只执行一次
for (属性in对象){}:循环遍历对象的属性;
if() 条件为 0/0.0/null/""/undefined/NaN 时为false
do{...;}while(条件);
switch(){case x:..;default:...;}
label:标签 可以在break和continue中使用: 标签:语句;
with(对象){} 将作用域设置到一个特定的对象中,去除多次写对象名的麻烦,严格模式下不允许使用;
对象:
JavaScript 中的所有事物都是对象:字符串、数字、数组、日期等等。
内置对象: ES标准中规定的,浏览器厂商已经实现的内置类型: 11个:
Object Function Array Date RegExp 包装类型(String Number Boolean)单体内置对象(Error Math Global (在浏览器中被window对象替代) )
引用类型和基本包装类型区别:对象的生存期:new创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中;基本包装类型只存在于一行代码的执行瞬间然后立即被销毁,所有不能再运行时为基本类型值添加属性和方法。
包装类型: 专门封装原始类型的值,并提供操作原始类型的值的方法
为什么: 原始类型的值不包含任何功能。但是,实际开发中,需要对原始类型的值反复执行相同的操作。
解决: 提前定义包装类型,集中保存该类型常用的操作方法。每次对原始类型数据调用方法时,都临时用包装类型包裹原始类型的值。
何时使用包装类型: 不用主动使用;当试图用原始类型的值调用方法时,自动创建包装类型的对象。封装原始类型的值。实际调用的,其实是包装类型对象的;方法调用后,自动释放!
对象是属性和方法的集合;对象可以嵌套对象;对象是引用类型的值,属性值是除undefined以外的值
js包括一个原型链特性,允许对象继承另一对象的属性,正确的使用能减少对象初始化的时间和内存的消耗
使用完较大的对象主动赋值null释放对象的引用
js底层一切对象都是hash数组,每个属性和方法都是hash数组中的元素
检索:优先考虑 . 表示法,其次[];
|| 可以填充默认值:var middle=stooge["middle-name"]||"(none)";var middle=stooge.name||"unknown";
尝试检索一个undefined值会导致TypeError异常,可通过&&运算符来避免错误
stooge.name //undefined
stooge.name.model //throw "TypeError"
stooge.name&&stooge.name.model //undefined
引用:对象通过引用来传递,它们永远不会被拷贝,同引用指向同一个对象,修改会互相影响值
var x=stooge; stooge对象和x指向同一个对象的引用
var a={ },b={ }; a,b引用不同的一个空对象
a=b={}; a,b引用同一个空对象
原型:原型关系是一种动态关系,原型连接只有在检索值时才被用到;
每个函数都有一个prototype属性,该属性引用的就是原型对象,
委托过程:若对象自有属性没有,则会从原型对象中获取,以此类推直到Object.prototype,否则返回undefined
每个对象都连接到一个原型对象并从中继承属性。原型对象属性值改变会影响素有继承该原型的对象
Function.prototype.originalToString = Function.prototype.toString;覆盖原toString前(系统已有方法前)最好存储指针,否则toString会被回收
原型链(prototype chain):由各级对象的__proto__属性,逐级继承,形成的链式结构
获取原型:obj为构造函数对象,obj1为实例/子对象
对象字面量/直接量的原型为Object.prototype;Object.prototype是所有对象的原型
new创建的对象使用构造函数的prototype作为原型:obj.prototype
"方法"保存在对象的构造函数的prototype中。
Array.prototype : 包含了所有数组类型可用的API
String.prototype : 包含了所有字符串类型可用的API
fobj.isPrototypeOf(cobj) 判断fobj是否是cobj的父级对象/cbj是否继承fobj,是则返回true;检查所有父级对象
obj1 instanceof obj; 判断是否是构造函数的实例
obj1._proto_ _protp_是内部属性;
Object.getPrototypeOf(obj1);
操作属性property:添加 =属性名 即修改属性
obj1.属性 自有属性,obj1[属性]
obj1.hasOwnProperty("属性"); 检测obj1是否具有自有属性,有则返回true
obj.prototype.属性; 共有/原型属性
!obj.hasOwnProperty("属性")&&obj.属性!==undefined
属性 in obj1; in检测对象及原型链中是否具有指定属性
!obj1.hasOwnProperty("属性")&&属性 in obj1; 同时使用has..和in可以确定属性是在对象还是原型
typeof obj1.属性 操作符,确定属性类型,会检查原型链:
无法区分数组对象和普通对象的类型
解决:1.Array.prototype.isPrototypeOf(obj1); 判断原型对象
2.obj1 instanceof Array判断构造函数
3.Object.prototype.toString():获得对象的class,每个对象都有class内部属性,记录创建对象时使用的类型名:
内置类型重写了toString不返回class属性,
call:强行借用一个函数,并临时替换函数中的this为指定对象
Object.prototype.toString.call(obj)==="[object Array]";
4.Array.isArray(obj1);
遍历:for in遍历一个对象中所有属性名,但属性顺序不确定
数组遍历:属性顺序确定但仅限数组字面量
Object.keys(obj1); 不包括不可枚举的属性
Object.getOwnPropertyNames(obj1); 所有属性
删除:delete 对象.属性; 运算符,不会移除原型链的任何对象,试图删除不报错也无法删除
减少全局变量污染:多个变量整理在一个名称空间下,在应用中值创建唯一一个全局变量
var app={}; app.stooge{属性:属性值...}; app.fligth={...};
封装:把数据或方法存储在对象中;
继承:从其他对象获得属性和方法
多态:重写override,子对象重写父对象继承的成员
定义构造函数constructor
①工厂方式:
缺点:每次调用函数,都会创建新方法
function create() {
var obj = new Object;
obj.color = "blue";
obj.show = function() {this.属性名;};
return obj;
}
var obj1 = create(“...”,....);
在工厂函数外定义对象的方法:
function create() {
var obj = new Object;
obj.color = "blue";
obj.show =show;
return obj;
}
function show(){....;}
var obj1 = create(“...”,....); obj1.show();
在工厂函数外定义对象的方法,然后通过属性指向该方法
②构造函数方式:通过function模板创造新对象;构造函数内没有创建新对象
代码重用,都会创建新方法;也可将方法写在外部;缺点:无法节约内存,用继承解决
function create(){
this.color=xxx;
this.xxx=xxx;
this.xxx=function(){...;};
}
var obj1=new create(“...”,...);
③原型方式:利用了对象的 prototype 属性
function create() {}
create.prototype={ //重写prototype对象,constructor不再指向原函数,指向Object
color : "blue",
arr :new Array("Mike","John"),
show :function() {...this.xxx;}
}; //或create.prototype.xxx = function() {...this.xxx;};
var obj1 = new create();
该方式可检查指向的对象类型:obj1 instanceof create; //true,
缺点:对象里方法可共享,同样对象里定义的对象也会共享:obj1.arr.push("Bill");会影响所有obj的数组内容
④混合的构造函数/原型方式:即用构造函数定义对象的所有非函数属性,用原型方式定义对象的函数属性(方法)。结果是,所有函数都只创建一次,而每个对象都具有自己的对象属性实例。
⑤动态原型方法:即在构造函数内定义非函数属性,而函数属性则利用原型属性定义。唯一的区别是赋予对象方法的位置
function create(sColor) {
this.color = sColor;
if (typeof create.f== "undefined") {
create.prototype.showColor = function() {... };
create.f= true;
}
}
⑥混合工厂方式:尽量避免,创建函数与工厂方式相同,但是使用new创建实例;
目的是创建假构造函数,只返回另一种对象的新实例。目的是创建假构造函数,只返回另一种对象的新实例。
继承inherits:通过原型实现,修改原型后,原有同名属性值不改变,且变为自有属性
自定义继承:obj为构造函数,obj1=new obj()为对象;obj1._proto_=obj.prototype
1.子对象._proto_=父对象; 修改单个对象的原型,修改obj1的父对象为fobj2,
2.Object.setPrototypeOf(子对象,父对象); 修改单个对象的原型,
3.构造函数.prototype=父对象; 修改构造函数的原型,为构造函数创建的对象指定统一的父级对象
注意: 修改原型后创建的心对象均使用新原型,修改前的对象使用旧原型
B.prototype=new A(); //B,A为构造函数,new A()为父级对象
4.两种类型间的继承: 最像Java中的继承,既扩展结构(extends),又继承原型(inherit)
1) 集中定义父类型属性和方法: 抽象:集中定义公共属性
function father(c1,c2...){...;}
father.prototype.xxx=function(){...}
2) 定义子类型的扩展属性和方法,借用构造函数: 在子类型构造函数中调用父类型构造函数
function child){
...;
father.call(this,c1,c2...); 或 father.apply(this,arguments);
}
//call,单独传入每个参数;apply,传入数组,可打散数组元素
3) 让子类型的原型继承父类型的原型:
Object.setPrototypeOf(child.prototype,parent.prototype);
ES5:
属性:
1. 命名属性: 自定义的属性.直接访问的属性;数据和访问器属性可通过defineProperties同时设置
1) 数据属性: 存储属性值的属性
特性Attribute:
value: 存储属性值,默认undefined
writable: 能否修改属性值,false为只读
enumerable: 属性能否被for in遍历到,用.依然可访问到
configurable: 能否删除属性/修改以上特性,改为false则不可逆
获取属性:Object.getOwnPropertyDescriptor(obj,"属性"); 返回封装了四大特性的对象
修改属性:添加属性并设置特性,除value其余特性不写默认为false(普通创建属性默认true);
若存在则修改原有特性;
Object.defineProperty(obj,"属性名",{
value:值,
writable:true/false,
enumerable:true/false,
configurable:true/false
})
同时设置多个属性:在构造函数内使用该方法且obj为this可以设置多个函数内对象
Object.defineProperties(obj,{
属性名1:{四大特性},
......
})
2) 访问器属性: 不直接保存属性值,为另一个数据属性提供可自定义保护规则的特殊属性;
特性:
get:读取属性时自动调用的函数,不提供则表示该属性值不可读取
set:写入属性时自动调用的函数,不提供则表示该属性值只读
enumerable: 属性能否被for in遍历到,同数据属性
configurable: 属性能否被删除/修改,同数据属性
不能定义但可通过设置访问:
Object.defineProperty(obj,"属性名",{
get:function(){return 属性的值},
set:function(value){ /*自定义规则如范围等*/....属性=value;},
enumerable:true/false,
configurable:true/false
})
强调: 不要用同对象的另一个属性保存实际数据。因为极容易被篡改。
解决: 使用闭包封装一个受保护的局部变量。
公有属性:this.属性名 都是公有属性;.都能访问到
私有属性:只在对象内部可用的属性,在外部用.访问不到的属性,受闭包保护的一个局部变量。
function Emp(name,...,age){//private,局部参数,私有变量
this.name=name; //左this.name为public,公有变量,右name为传入参数
....;
var _age; //private,私有变量
Object.defineProperties(this,{
xxx:{四大特性},
age:{//为当前对象添加访问器属性age
get:function(){return _age;}.
set:function(val){
规则;
_age=val;//满足条件则赋值
}
}
})
this.age=age; //注意顺序,右边传入参数后,左边触发age的set访问器,改变_age值
//则访问this.age后触发get传出_age值
}
在构造函数内
1)凡是this.属性名 都是公有属性
2)如何实现私有属性: 2步:
Step1. 定义一个局部变量,实际存储属性的值
Step2. 定义一个访问器属性,访问器属性的get和set方法都保护局部变量
强调: 在访问器的get/set方法内访问局部变量不要加this
2. 内部属性: 自动包含的,不允许外部随便访问,
_proto_:继承,引用当前对象继承的原型对象
class:对象的类型名,不能访问;可通过Object.prototype.toString()打印出来且第二部分即为类名[object Array]
Extensible:可扩展,表示能否为对象扩展新属性,默认true,false则不可扩展
防篡改: 3个保护级别:
1. 防扩展: 禁止向对象中添加新属性:
Object.isExtensible(obj):是否可扩展
Object.preventExtensions(obj):修改Extensible为false,不可逆
2. 密封: 在防扩展基础上,禁止删除属性,修改属性的特性;仅可以修改属性值
Object.isSealed(obj):是否密封对象
Object.seal(obj);密封,不可逆
原理: extensible为false上,所有属性的configurable都改为false
3. 冻结:所有属性禁止增减,属性值禁止修改(私有属性除外)
Object.isfrozen(obj);
Object.freeze(obj);冻结
原理: 在密封的基础上,所有属性的writable改为false
何时使用: 专门定义一个对象,集中保存程序中使用的所有常量属性。
为了保证对象内的常量属性不被修改,都要将整个对象密封起来:Object.freeze(obj);
Object:
Object是Object类型的构造函数,typeof(Object)返回的是function
Object.prototype对象才是所有对象的父对象
Object构造函数:
Object():不传入/传入参数null,undefined==new Object(),创建空对象
Object(原始类型值)==new Object(原始类型值):将原始类型值转换为Object类型
Object(引用类型的对象):返回原对象
方法:Object.getPrototypeOf(obj)
Object.getOwnPropertyDescriptor(obj,”属性名”):返回对象中指定属性的特性
Object.getOwnPropertyNames(obj):获得对象中所有属性名的数组
Object.keys(obj) 仅返回可被枚举的属性名组成的数组
Object.create方法:创建新对象并继承fobj对象,同时扩展多个自有属性,第二个参数可忽略
Object.create(fobj,{
属性名1:{四大特性},
......
});
特殊用法:
var o=Object.create(null); 创建一个原型为null的空对象
Sub.prototype=Object.create(Object.prototype); 子类型构造函数的原型继承福类型构造函数的原型
var o=Object.create(Object.prototype); === var o={};创建普通空对象
Array:
检测数组:
typeof [] 无法检测数组对象,返回object
[] instanceof Array 返回true/false
Object.prototype.toString.call([]) 返回[object Array]
Array.prototype.isPrototypeOf([]) 返回true/false
Array.prototype.indexOf=function //原型/实例方法:必须用具体对象才能调用
arr.indexOf();
Array.isArray=function //构造函数方法:不需任何具体对象
Array.isArray(obj)
查找元素位置:
arr.indexOf(元素值,开始下标); 找不到返回-1,元素值进行全等比较
arr.laseIndexOf(元素值,开始下标)
迭代方法:
fun函数接收三个参数:(元素值val,当前元素位置idx,数组对象array);
参数每次循环都会重置,所以不能修改参数本身
arr.every(function(val,idx,array){...}); 数组每个元素是否满足fun函数条件,必须返回布尔值,满足返回true
arr.some(function(..,..,..){...}); 判断数组元素有满足fun。。。。其余同上
arr.forEach(function(..,..,...){...}); 对数组每个元素执行fun操作,不需返回值,直接修改原数组
arr.map(function(..,...,...){...}); 对数组每个元素执行fun操作并放入新数组中
arr.filter(function(..,...,...){...}); 筛选数组中符合fun函数条件的元素组成新数组,必须返回布尔值
归并方法:
fun参数:汇总值(第一次为arr[0],若无相关规则为undefined);当前值(从arr[1]开始);索引;数组对象
arr.reduce(function(prev,curr,index,array){...})从左向右迭代数组每个元素,
arr.reduceRight(fun(...){...})从右向左
Function:
新函数对象=原构造函数.bind(实例对象)
新函数对象=原构造函数.bind(实例对象,原函数参数值)
基于某函数,创建某对象专用的方法,同时提前绑定this值或设置参数值
严格模式:
将不合理的行为变为错误;修正一些引擎难以优化的错误;禁用一些未来新版本中使用的语法和关键字
<script>“use strict”;..........</script> script开启严格模式,放在所有语句前
function(){“use strict”;..........} 函数启用严格模式
不能给为声明变量赋值,非严格模式转为全局变量
eval(“use strict”;.str) 严格模式多了eval作用域,保存其中创建的变量,不会影响外部同名变量的值
arguments 不再随参数变量的值改变而改变
不允许调用arguments.callee
禁止不在全局或函数层面上的函数声明,如在if,for{}内声明
public,static,private,package,let,protected,yield,interface,implements变成保留的关键字
引用类型:
①object类型
声明:⑴字面量表示法:
var obj={
属性名:值,
...
方法名:function(){this.属性名;}
};
或:var 对象={};
⑵new创建:
var obj=new Object(); 若没有参数可省略()
obj.属性名=值;
obj.方法名=function(){this.属性名};
调用:obj[alert(10)/属性]; obj.方法();
访问到不存在的属性,不会报错,返回undefined。
⑶函数创建对象构造器:
函数传递对象:函数({...,属性:属性值});
访问对象的属性,结果为属性值:对象["属性"]/对象.属性; []内必须是str类型
属性名包含空格、减号、关键字必须引号
属性不存在/属性值本身是undefined返回undefined
检测属性:
⑴属性 in 对象;
⑵对象.hasOwnProperty(属性值);
⑶对象.属性===undefined;
⑷if(对象.属性){存在;} undefined/numm/0/空字符串会自动转换为false
方法定义:
⑴函数名作为指针传递给对象的某属性
⑵对象内定义var x={属性:function(){}};
⑵构造器函数内部定义对象的方法:
function 函数构造器(参数){
this.参数1=属性1;
...
function 方法(参数){
...
}
}
对象=new 函数构造器(属性值);
方法:toString()、toLocaleString()、valueOf()
②Date类型:原理: date对象中封装的是一个1970年1月1日0点至今的毫秒数。
创建:
var now=new Date(); 创建并获得客户端系统时间;
var date=new Date("yyyy/MM/dd hh:mm:ss"/yyyy,MM-1,dd,hh,mm,ss);创建日期对象,并自定义时间
var date2=new Date(date1) 复制一个日期对象
方法:除了Date,其余都从0开始,到进制-1结束
以下每个分量都有一对get/set方法,
FullYear 年份
Month 月份0~11 修正为1~12
Date 日期1~31
Time 返回与UTC时间1970.1.1午夜时间相差的毫秒数
Hours 小时0~23 不用修正
Minutes 分钟0~59 不用修正
Seconds 秒0~59 不用修正
Milliseconds 毫秒0~999 不用修正
其他:
getTimezoneOffset:返回本地实际与GMT(格林威治标准实际)的分钟差
getDay:返回星期(0~6) 不用修正,∵0:日;1:一...
计算:两个日期可相减,结果是毫秒差
获得分量;+/-n;并设置:data.setxxx((data.getxxx)+/-n) setxxx可自动调整进制
格式转换:
toString(); //将date转为国际标准时间格式
toDateString()
toTimeString()
toLocaleString();//转为当地完整标准时间格式
toLocaleDateString();//当地时间格式,仅保留日期
toLocaleTimeString();//当地时间格式,仅保留时间
toGMTString()
toUTCString()
问题:以上API可能造成浏览器不一致
解决:自定义format方法,格式化任意一个日期对象
③Function类型:函数/方法Method/过程Procedure
函数对象连接到Function prototype,有两个附加隐藏属性:函数的上下文和实现函数行为的代码(调用属性)
值传递:对引用类型的对象: 通过新变量修改对象=直接修改原对象;对原始类型的值: 修改新变量,不会影响原变量
函数参数:形参parameter;调用参数:实参argument;
局部变量会在函数运行以后被删除;全局变量会在页面关闭后被删除。
函数 vs 方法:相同: 本质都是function;差别: 函数不属于任何对象,方法指特定对象内的函数
函数名是指向函数的指针,可像传递参数一样传递给其他变量/函数;同样功能的函数可以有多个名字
位于return语句后的代码永远不会执行,没有return则始终返回undefined
声明:
①function 函数名(参数){return 返回值;} 声明函数;函数名必须
②var 变量/函数名=function(参数){......;}; 函数表达式,通过变量调用函数;适合只会用到一次的函数
函数名可选,且该名称为函数内局部变量,并指代函数对象本身
③var Add = new Function("a", "alert(a + 10)"); new创建的参数,函数体为字符串形式
用Function对象创建,所有函数都应看作 Function 类的实例;
同名函数多次编写,没有重载overload,会覆盖
声明提前:解析器会先读取函数声明(在执行任何代码前),所以函数表达式会覆盖函数声明
函数表达式需执行到它才会执行,函数表达式必须放在调用函数之前,
声明/直接量定义的方法体固定,无法在运行时动态执行;new创建的方法体是字符串,可以在运行时动态创建修改并执行字符串格式的方法体
以new方式定义的函数,因为函数体是字符串,需要再次解析所以执行效率低
*****函数的生命周期:
程序开始执行时:
1. 创建执行环境栈: Execution Context Stack专门按调用顺序保存每个函数的执行环境的集合
开始执行程序时,首先压入全局执行环境。
2. 创建全局作用域对象: window,保存所有全局函数和变量。其实window对象就是全局作用域对象。
3. 在ECS中压入第一个元素:全局EC 引用 window
ESC只是存储调用变量的顺序,不存储任何变量
定义函数时:
1. 创建函数对象,封装函数定义
2. 用函数名创建一个变量,函数名变量引用函数对象
3. 在函数对象中,添加scope属性指向创建函数的作用域:引用函数来自的作用域对象,通常都引回window
调用前:
1. 向ECS中压入一个本次函数调用的EC
2. 创建一个活动对象Actived Object,封装所有局部变量;AO:保存函数调用时的局部变量,其实AO对象就是函数作用域对象
3. 在AO中添加parent成员,让本次函数调用的EC引用活动对象AO
4. 让AO再指向函数的scope属性引用的对象,引用函数来自的父级作用域对象, 由此形成作用域链。
调用中:
变量使用规则: 优先使用局部的,局部没有,才用全局的
调用后:
1. 本次函数的EC出栈
2. AO释放,AO中的局部变量一同释放
作用域和作用域链:
作用域: 变量的可用范围,其实就变量的存储位置
只有2种: 全局作用域:window对象
函数作用域:AO对象
作用域链: 当前函数的EC中的scope chain属性应用AO对象
AO对象再逐级引用,直到window结束,形成的链式结构
用途: 保证如果AO中没有变量,可继续延作用域链继续到window找
函数内部对象:
⑴arguments 类数组对象,包含着传入函数的所有实参;调用:arguments[0]访问第一个参数
arguments.callee 指向函数,代替函数名,作用:解除耦合,正常完成递归调用
arguments.length 函数实参个数;
无关形参,通过arguments.length控制可以接收任意数量>0的实参
实参>形参时,多余的实参将省略且arguments[n]=undefined
类数组对象使用call,也可让类数组对象使用Array的共有方法。
(function (){ Array.prototype.sort.call(arguments);
for(var i=0;i<arguments.length;i++)
console.log(arguments[i]);
})(1,2,3,12,23,123);
⑵this
this对象方法内表示当前对象;构造函数中表示正在创建的新对象;匿名函数内this默认都指向window
嵌套函数作为函数调用,this值为全局对象window(非严格模式)/undefined(严格模式)
this不能赋值不会继承;可以用变量self保存this值
嵌套函数作为方法调用,this值指向调用它的对象;
html调用函数内代替 当前标签节点
函数内部对象的属性:
caller:调用 当前函数的 函数的引用,全局作用域调用值为null;匿名函数递归调用自身
function f1( ){ f2( ); }
function f2( ){ f2.caller; }
因为f1()调用了f2();所以f2.caller指向f1()
函数属性和方法
f.length属性: 函数形参个数
f.prototype属性:保存所有实例方法,但不可枚举(for in无法发现)
在特定的域中调用函数:this指向f,同时传递参数
apply():f.apply(this,参数); 作用域:this/object;参数数组:arguments/[..,..]数组形式
call():f.call(this,n1,n2..); 实参列表,调用一个对象的一个方法,用另一个对象替换当前对象
bind():在函数上调用可改变其函数内部this指向,并且返回一个新的函数;
改变this方向指向obj
var fobj=f.bind(obj); fobj();即可有obj参数的方法
f.toString()/f.toLocaleString/f.valueOf()/f.prototype.constructor 返回函数源代码,调试用;typeof为string/function;
this:指代真该调用方法的对象(.前的对象)
obj.method(); //method中的this-->obj
如果一个函数,没有任何对象调用,其中this默认指window
method();//method中this-->window
匿名函数自调:匿名函数内this-->window
匿名函数回调:arr.sort(function(){this-->window;})
特例:jquery中$(selector).each(function(){this-->DOM元素})
事件处理函数:this-->绑定处理事件的元素对象
如果this不是想要的:
需要立刻执行的函数:call/apply临时替换this
替换回调函数中的this:bind永久替换
=>
给类型添加方法:
Function.prototype.menthod=function (name,func){this.prototype[name]=func; return this;};
通过给Function.prototype增加一个method方法,就不必键入prototype这个属性名
匿名函数:
定义时未指定名称:声明时无函数名;直接定义(function(){;})
仅在调用时临时创建函数对象和作用域链对象,调用完立即释放;非匿名函数定未调用也占用内存空间
回调函数:将一个函数,传递给另一个函数去调用
fn(function(){return 1;},function(){return 2;});
自调函数:创建一个函数后,立刻调用,调用完,立刻释放!
var n=( function(x){return x*x;}(10) );或(function(){...;}()); 函数表达式定义后立即调用
闭包:既重用,又保护变量不受污染的机制,且使垃圾回收器无法回收
外层函数包裹受保护的变量和操作变量的内层函数;
内层函数返回return;
外层函数将内层函数return;
调用外层函数,获得内层函数的对象;
闭包作用:
提供可共享的局部变量;
保护局部变量,提供专门读写变量的函数;
避免全局污染
闭包内无法直接访问外部函数的this/arguments,但可以将这些存为变量,然后给闭包调用
每调用一次外层函数,就会创建一次闭包;
同个闭包多次调用可保留变量值
同一次外层函数调用返回的多个内层函数,共享同一个变量。
返回内层函数的多种方式:
1). 直接return
2). 直接给全局变量赋值,不建议
function fun(){
var i=999;//受保护的局部变量
window.nAdd=function(){i++}; //或nAdd=... 全局变量
return function(){console.log(i)}
}
3). 将函数装在数组或对象中返回
①function f(v){return function(){return v;}}
var a=[]; a[0~n]=f(n); 创建一次闭包 a[n]();...调用:n个闭包,n个变量副本,变量之间不共享
②unction fun(){ //受保护的局部变量: i
for(var i=0,arr=[];i<3;i++){
arr[i]=function(){console.log(i);}
}
return arr; //i=3
} 同一次外层函数返回多个内层函数,共用一个变量i(同一个调用函数内定义)
var arr=fun(); //外层函数只调用了一次,只有一个i副本
//arr[//i=3
//function(){console.log(i);},
//function(){console.log(i);},
//function(){console.log(i);},
//]
arr[0]();//3 arr[1]();//3 arr[2]();//3
③
function counter(){
var n=0;
return{count:function(){return n++;} reset:function(){n=0;}};
}
counter().count(); 创建一次闭包并调用一次
函数调用:作为函数;作为方法;作为构造函数;通过它们的call()和apply()方法间接调用
调用表达式:
函数调用:函数的return返回值成为调用表达式的值,通常不使用this,但可以用来判断当前是否是严格模式
方法调用:(1)定义:o.add=f; 调用:o.add(x,y);或o["add"](x,y);
(2)var obj={.
name:1;
add: function(){
this.name=2; //this指代当前对象obj
}
};
函数可作为值/参数/返回值,使用不带圆括号的函数名是访问函数指针而非调用函数
ex:var a=[function(x){return x*x;},20];a[0](a[1]); //400;a[1]函数作为值,a[0]()函数调用
function fn(f,x,y){return f(x,y);} f1(x1,y1){...;}.... fn(f1,x1_,y1_); fn函数调用;f1作为值,函数调用
var f={ f1:function(x1,y1){...;}, ...}; function fn(f_,x,y){return f[f_](x,y);} fn(f1,x1_,y1_)
fn函数调用;f1作为值,方法调用
方法链:f().m(); f()调用结束后继续调用返回值(返回值是一个对象)中的方法m()
方法不需要返回值时最好直接返回this,则可进行链式调用
可选形参:function(o,p){p=p||[];}如果参数p没有传入则创建一个空数组并赋值给p
④RegExp类型:
可检索、替换、提取;由于str类型只读,不方便替换;或许有其他语言的方法?
正则表达式regular expression是由普通字符(如a~z),特殊字符(元字符metacharacte)组成的文字模式
检测软件:RegexBuddy选项:match,语言:javascript;^$match at line breaks
注意转义的:
. \ / * ? + [ ( ) ] { } ^ $ | -
所有转义字符,正则表达式的所有字符
直接量字符:
字母和数字字符
转义字符:
\n 换行\u000A
\t 制表符\u0009
\v 垂直制表符\u000B
\r 回车符\u000D
\f 换页符\u000C
\o NUL字符\u0000
\xnn 十六进制数nn指定的拉丁字符 \x0A==\n
\uxxx 十六进制数指定的Unicode字符 \u0009==\t
\cX 控制字符^X, \cJ==\n
字符类:字符unicode连续,可用-省略中间的字符
[...] 方括号内任意字符 [\u4e00-\u9fa5]一位汉字 []不能匹配n位数
[^...] 不在方括号内任意字符字符,^必须放在[]开头
. 除回车,换行符和其他Unicode行终止符以外的任意字符
\w 一个ASCII字符组成的单词:字母/数字/下划线,等价于[A-Za-z0-9_]
\W 一个不是ASCII字符组成的单词
\s 一个Unicode空白符:空格符,制表符,其他Unicode空白符,等价于[ \f\n\r\t\v]。
\S 一个非Unicode空白符的字符
\d 一个ASCII数字
\D 一个非数字
[\b] 退格直接量,特例 [\s\d]匹配任意空白符/数字
量词:前一项
* >=0次
+ >=1
? 0/1次,可选
{n} n 次, [0{2}]===[00] 匹配0,不匹配00
{n,} >=n次
{n,m} n ~m 次
注意:* ?允许什么都不匹配
贪婪匹配:默认情况,正则表达式匹配最长的符合条件的子内容
懒惰模式: 让正则表达式仅匹配最短的符合条件的子内容;截取网址等
贪婪改懒惰:*? +? ?? {n}?
选择和分组/引用字符:
exp1|exp2 从左到右匹配,exp1存在则只能匹配第一个字符
(exp1) ⑴分组;
⑵定义完整模式中的子模式:从目标串中抽出与子模式匹配的部分给$n使用
⑶允许在表达式后部引用前面的子表达式\n
['"][^'"]*['"] :匹配中间没有'",且用'或"两边括起来的字符
(['"])[^'"]*\1 :在上面条件上,要求两边引号相同;\1引用第一个圆括号内容
(?:...) 只组合,不记忆与该组匹配的字符:不会产生\n自动编号
\n 引用第n个带圆括号的子表达式;不是单纯的对表达式的引用,是对模式相匹配的文本的引用;按左括号
位置/锚字符:
^ 字符串开头;多行检索中匹配一行开头
$ 字符串结尾;.....
\b 一个单词(字母组成)边界:^ $ \s 标点
\B 非单词边界
(?= x ) 向前正向匹配;匹配其后紧接x的字符串
(?! x ) 向前负向匹配;匹配其后没有紧接x的字符串
修饰符:
可组合应用/is/igm
i:ignoreCase,不区分大小写
g:global,全局匹配,多次匹配
m:multiline,多行匹配
操作符优先级:
\ 转义符
(), (?:), (?=), [] 圆括号和方括号
*, +, ?, {n}, {n,}, {n,m} 限定符
^, $, \anymetacharacter 位置和顺序
| "或"操作
密码强度 由数字,字母组成,至少一位大写字母和一位数字(?![A-Za-z]+$)(?![a-z0-9]+$)[A-Za-z0-9]{6,9}
创建对象:
正则表达式字面量:
var patt1=/pattern模式/flags标志; var i=/ \d{2,3} / ig;
共享一个RegExp实例
调用RegExp构造方法:
var patt2=new RegExp(pattern,flags); var i=new RegExp(" \\d{2,3} "," ig ");
所有元字符和转义字符需进行双重转义
创建的每一个新RegExp实例都是一个新实例
属性:
.lastIndex:获取下次匹配的字符位置(从0算起);没有指定g修饰符的不能使用
global:只读,RegExp对象是否有g修饰符
ignoreCase: 只读,i
multiline:只读,m
source:只读,返回正则表达式的字符串形式(字面量形式)
$1...$9:全局属性,指代最近一次搜索中某个子表达式匹配的文本
方法:
Regexp方法:影响lastIndex属性的值
compile() 编译/重新编译正则表达式,将pattern转换为内部格式,加快执行速度
valeOf() 返回reg本身
reg.test("str") 检索字符串中指定的值,返回true/false;影响lastIndex属性的值
reg.exec("str") 检索字符串中指定的值,返回一个(第一个)匹配项的数组形式,否则返回null
arr.[0]:匹配项
arr.[n]:$n
arr.index 返回关键词的位置,
影响reg.lastIndex属性的值,每次查找后,改为当前位置+关键词字符个数,即下次开始位置
不设置g,始终返回第一个匹配项
设置g,每次调用接上次位置检索,直到返回第一个匹配项
String方法:不影响lastIndex值,除search其余未找到返回null
str.search(reg) 返回第一个与之匹配的子串的起始位置n;否则返回-1;不支持且会忽略g
str.match(reg) 由所有匹配结果组成的数组
不设置g,返回第一个匹配,数组[0]存放完整匹配,a[n]存放$n内容
str.split("分隔符"/reg,数组大小) 匹配reg/分隔符检索,将一个字符串分割成多个字符串并放在一
个数组中,分隔符丢弃;1/2参数
Split方法的reg中,尽量不要使用(),否则会按照子模式再切割。
str.replace(reg,str2/函数) 检索str,匹配regexp的字符串,替换为str2,返回str类型
重要特性:
⑴第二个参数中可用$n作为字符串一部分/函数参数
" \"cat\" ".replace(/" ( ... ) "/," |$1| ");匹配"cat",替换为|cat|;$1引用第一个圆括号内容
⑵关键词屏蔽技巧:replace调用函数
高级替换:str.replace( regexp,function(kw,$1,$2.....){return 替换内容;} );
str=str.replace(regexp,funciton (kw,$1){kw和$1的关系;return kw.length=2? "**" : "***";});
匹配满足regexp的内容,2位数替换为**,其余替换为***
⑶衍生:
删除:将关键词替换为" "
格式化:正则()匹配分组,用含有$n表达式替换;如19831226格式化为1983年12月26日
可以通过判断返回null/-1,隐式控制循环和赋值/输出:(方法!=null/-1)&&(赋值/输出)
⑤array类型
js提供一些类数组特性的对象,把数组的下标变成字符串,用其作为属性
数组字面量声明:
var arr=new Array( ); 用Array构造时new可省略
var arr=new Array(n); 创建length为n的数组
var arr=new Array("red","blue"); 创建length=2的数组
var arr=[]; 空数组
var arr=["red","blue"];
var arr=[[...],[...]...] 二维数组,r/行不能越界
对象字面量声明:var 数组={"0":"数1","1":"数2"...};
数组字面量继承Array.prototype,有length属性;对象字面量继承自Object.prototype,没有length属性
末尾添加新项:数组[数组.length]="..."; 添加后length自动更新,数组元素未赋值默认undefined
可通过array[0]/array["0"]调用,不能通过array.0调用,可能是因为命名规范(首位必须为字母)导致;首位为字母则两者都可调用
稀疏数组:如果i越界,js会自动在i位置创建新元素和值;会造成下标不再连续
数组分为索引数组(下标数字)和关联数组(下标自定义),关联数组length永远为0
for( key in arr)遍历关联数组;in依次把arr中每个元素的下标名称保存在key中
关联(hash)数组的原理:
hash算法: 接收一个字符串,计算出一个尽量不重复的序号
相同的字符串,计算出的序号一定是相同
不同的字符串,计算出的序号尽量不同
存储: 将自定义下标名称交给hash算法,计算出一个尽量不重复的序号。将要保存的数据,存入序号的位置。
取值/查找: 将要查找的下标名称交给hash算法,再计算出和存入时一模一样的序号,直接去数组指定位置获取
元素内容。
优点: 查找速度极快;不用遍历,查找速度和元素个数与数据量和存储位置无关!
转字符串:返回新数组
String(arr) 返回数组项的字符串形式组成的,分隔的字符串(非数组)
.toString()
.valueOf() 返回数组,数组项类型不变
toLocalesString()
.join("自定义分隔符"): 将数组转为字符串,可自定义分隔符;省略"",等效于String了
固定套路:
1. 将单词数组,拼接成句子: arr.join(" ")
2. 无缝拼接: arr.join("")
3. 将数组转化为页面元素: 用join拼接</结束标签><开始标签>;再拼接开头和结尾
拼接和截取: 返回新数组
.concat(n1,n2,arr2,...) arr1+n1+n2+arr2,可以打散数组类型参数为单个值
.slice(n1,n2); -n表示倒数第n个元素<==>length-n
获取arr中n1位置开始,到n2位置的所有元素组成新数组, 含头不含尾;
第二个参数可省略,表示从n1一直获取到结尾
lis=[].slice.call(lis);
直接修改原数组:
.splice(n,num,n1,n2...): ;返回删除的项,如果没有则返回空数组
删除:splice(n,num); n为起始位置;num为删除的项数;n1,n2为插入值1,插入值2...
插入: splice(n, 0 , n1,n2,...) 不能插入数组,否则会形成子数组
替换: splice(n,num,n1,n2...)
栈(stack)和队列(queue):直接修改原数组,栈LIFO后进先出,队列FIFO先进先出;
. push(n) 结尾入栈,
. pop(); 结尾出栈
. unshift(n); 开头入栈
. shift(); 开头出栈
位置方法:第二个参数n1为查找起点位置,可选
.indexOf(n,n1) 从数组开头向后查找n,返回第一次出现的位置/未找到-1;
.lastIndexOf(n,n1) 从数组末尾向前查找n
排序:直接修改原数组
.reverse(); 翻转数组元素
.sort(); 升序排列,默认将所有元素转为字符串再比较unicode
自定义比较器函数:
比较两个数字大小:function compare(a,b){return a-b;}
较两个字符串长度:function compare(a,b){return a.length-b.length;}
传入sort方法: arr.sort(compare);降序则改变b-a
简写:arr.sort(function(a,b){return a-b;});
手动冒泡排序:(快速,插入)
for(var r=1;r<arr.length;r++){
for(var i=0;i<arr.length-r;i++){
if(arr[i]>arr[i+1]){
var t=arr[i];
arr[i]=arr[i+1];
arr[i+1]=t;
}
}
}
检测数组:
arr instanceof Array
Array.isArray(arr)
Array.sort(arr) 对数组元素排序
固定套路:最后一个元素:arr[arr.length-1];最后第n个元素arr[arr.length-n];末尾追加arr[arr.length];缩容:arr.length-=n
⑥String类型:
多个字符组成的一个只读字符数组,所有方法不影响原字符串,转义字符、" 需注意用 \ 转义
Array中不直接修改原数组的API,字符串都可用: 如concat/slice/lastIndexOf/indexOf
str[n]可下标访问;
length属性 ASCII字符算一个字符
获取指定字符:
.charAt(n) 返回下标为n的字符;单字符串形式,ECMAScropt无字符类型
.charCodeAt(n) 返回下标为n的字符的字符编码unicode号
String.fromCharCode(n1,n2,...); 将几个数值的unicode号,反向还原为字符串
.charCodeAt().toString()检测字节数:"一".charCodeAt().toString(2)
获取子串:1/2参数(新子串开始下标m,结束下标n),不包含结束位置;
.slice(m,n) 所有负参数与length长度相加
.substr(m,n) 第一个负参数+length长度,第二个负参数转为0
.substring(m,n) (m,字符个数n);所有负参数转为0;解决:-n换位str.length-n
搜索子串位置:参数1/2,不支持正则,未找到-1
.indexOf("x",n) 从字符串开头/下标为n的位置搜索x子串,返回第一次出现的位置
.lastIndexOf("x",n) 从字符串末尾/下标为n的位置向前搜索x子串
大小写转换:只要不区分大小写时,都要先转换为一致的大小写,再比较
.toUpperCase()/toLowerCase() 大/小写
.toLocaleUpperCase()/toLocaleLowerCase() 针对特定地区,不知道代码在哪种语言环境运行的情况下使用
模式匹配:
.match(RegExp/str) 1个参数:正则表达式/RegExp对象;返回一个与正则表达式匹配的数组
.search(RegExp/str) 参数同上,返回字符串中第一个匹配项的索引;没有返回-1;不支持且会忽略g
.replace(RegExp对象/"substr","str"/函数) 替换所有字符串用RegExp对象且需指定全局g标志
其他:
.trim() 返回字符串的副本,删除前置及后缀所有空格
.concat("...","...",...) 返回新字符串,不影响本身值
.split("分隔符",指定数组大小) 通过分隔符检索,将一个字符串分割成多个字符串并放在一个数组中,分隔符
valueOf(),toString(),toLocaleString() 返回字符串值
丢弃;1/2参数
str1.localeCompare("str2")比较两个字符串,str1在前/相同/后 返回 负数/0/正数
⑦Boolean类型:不建议使用
var x=new Boolean(true/false);
重写了valueOf()返回基本类型值true/false,toString()返回字符串true/false
⑧Number类型:
Number() 相当于隐式转换,都是先去空格,再转换;将“”和null都隐式转为0
静态常量属性:
MAX_VALUE js可表示的最大数值
MIN_VALUE 最小数值
NaN 非数字值
NEGATIVE_INFINITY 负无穷大,溢出时返回
POSITIVE_INFINITY 正无穷大
方法:
num.toSring(n); 返回n进制数值的字符串形式;默认十进制
num.toFixed(n); 返回n位小数位数值的字符串形式;四舍五入
num.toExponential(n); 返回n为小数位的e表示法数值的字符串形式
num.toPrecision(n) 指定有效位数的字符串
重写了valueOf(),toString(),toLocaleString()
单体内置对象:
⑨Global对象:(全局函数)
URI编码:URI:通用资源标识符
encodeURI(uri); utf-8编码替换;主要用于整个URI;汉字被替换;空格被替换%20
decodeURI(enuri); 解码
encodeURIComponent(uri) utf-8编码替换所有非标准字符(除字母外);主要用于对URI某一段
decodeURIComponent(enuri);
原因:uri标准中,不允许出现多字节字符比如汉字,否则乱码
编码:将uri中的多字节字符,用utf-8编码为单字节字符;
解码: 将编码后的单字节字符,解码回多字节字符原文
eval("js"): 把字符串代码当做js运行,执行结果插入到原位置;js作用域和语句所在作用域相同
强大:解析字符串格式的数据结构,比如对象,数组;
注意: 如果传入的字符串语法错误,或无法执行,则报错
isFinite(num) 检测一个数字是否在有效范围内: true,有效范围内的数字;false
Infinity无穷大: js中,如果除数为0,不会报错会返回Infinity;可用isFinite判断,不是有效范围内
isNaN(num) 专门判断num是不是NaN;true :不是数字,false : 是一个数;
方法:isNaN(),isFinite(),parseInt(),parseFloat()等
属性:NaN,Infinity,undefined,Object,Array等
访问Global对象:
window对象:Global无法直接访问,可用window代替访问属性方法
另一种取得Global对象的方法:var global=function(){return this;}();
⑩Math对象:不能new
属性:
Math.PI π的值
Math.SQRT2 2的平方根
Math.SQRT1_2 2平方根的倒数
.E e的值;自然对数的底数
.LN2 2的自然对数(≈0.693)
LN10 10的自然对数(≈2.302)
LOG2E 以2为底的e的对数(≈1.414)
LOG10E 以10为底的e的对数(≈0.434)
方法:
Math.random() 0<=随机浮点数<1
min<=x<=max:parseInt(random*(max-min+1)+min)截断或Math.round(random*(max-min)+min)四舍五入
0<=x<=max::parseInt(random*(max+1)); 或Math.round(random*max)
Math.max(n1,n2,...) 确定一组数值的最大值
Math.max.apply(Math/null,arr); 返回数组最大值
Math.min.apply(Math/null,arr)
Math.min(n1,n2,...)
.ceil(n) 向上舍入,有小数整数部分+1
.floor(n) 向下舍入
.round(n) 四舍五入
.pow(x,y) x的y次幂
.sqrt(n) 开方
.exp(n) e的指数
.abs(n) 数的绝对值
三角函数方法:
Math.cos(n) 数的余弦
sin(n) 正弦
tan(n) 正切
acos(n) 反余弦值
asin(n)
atan(n) 以介于-PI/2与PI/2弧度之间的数值来返回n的反正切值
atan2(n) 从x轴到点(x,y)的角度(介于-PI/2与PI/2弧度之间)
错误处理:非正常运行状态称为异常/错误
解释器会为每个错误情形创建并抛出一个Error对象,其中包含错误的描述信息
err在出错时,自动获得错误对象,即使不使用,也不能省略!
Error对象:在发生错误时,封装错误信息的对象;
六种:EvalError,RangeError,ReferenceError,SyntaxError,TypeError, URIError
主动抛出异常:何时需要抛出自定义错误:函数的定义者希望提醒调用者错误的使用了函数时
可以使用Error构造方法创建自定义的Error对象,并使用throw语句抛出该对象if(){throw new Error(“...”);}
try应该仅包含可能出错的代码,普通代码放入执行效率会下降;finally可省略
解决:提前预知错误,用if else判断代替try结构,如果无法预判可能发生的错误,就用try catch
关于try catch中的return:finally中有return会覆盖之前的所有return;finally没有retruen,程序会先确定之前return的返回值,但是,暂不返回,等待finally中的代码执行完才返回,finally中的代码不会影响之前确定renturn的结果
属性:
message:封装异常的描述信息
name:封装异常的类型名称
stack:返回错误或异常的代码跟踪信息
方法:
toString():返回包含相关错误信息的字符串
ex:
var n=123.456,d=prompt("请输入小数位数");
try{//主业务功能代码中可能产生并抛出错误
document.write(n.toFixed(d));
}catch(err){//错误处理代码
alert("无效小数位数");
console.log(String(err));//记日志
}finally{//出口语句,不论错误发生与否都要执行
console.log("释放内存");
n=null;
}
Ajax:new XMLHttpRequest(); 判断浏览器是否支持Ajax
document.write(
window.XMLHttpRequest?"<h1 style='color:green'>您的浏览器完美支持Ajax技术</h1>":
"<h1 style='color:green'>您的浏览器版本太低,不支持Ajax技术</h1>"
);
①不声明第三个变量,交换两个数:
数字:x+=y;y=x-y;x-=y;
万能:y=[x,x=y][0];
例:x>y&&(y=[x,x=y][0]);x>y就交换
x>y时,执行下一条;y即[x,x=y]为2个项的一维数组,[x,x=y]使x=y,且y=下标为0的数组
i为匿名数组:i=[3,6][0] 则i=3; i=[3,6][0] 则i=6
②递归问题:函数体内递归函数本身,效率低
解决:多数递归可用循环代替
f(1)=1,f(2)=1,f(n)=f(n-1)+f(n-2)即使f(n)=f1+f2;f1=f2;f2=fn;
③素数/质数:n%(2~sqrt(n))==0则不是素数,反之是素数
④分解质因数
⑤最大公约数,碾除法;最小公倍数=n1*n2/最大公约数;
a>b
while(b!=0){
temp=a%b;
a=b;
b=temp;
}//a为公约数
a和onclick冲突