typescript

ts基础

vscode配置自动编译ts
1
2
3
tsc --init  //生成tsconfig.json文件
//在tsconfig.json文件 改 "outDir": "./js"
在导航栏找到 任务--> 监视 tsconfig.json
hbuild配置自动编译ts
  1. 在最上面菜单栏,点击工具——插件安装。
  2. 点击下方浏览Eclipse插件市场,搜索typescript插件进行安装
  3. 安装完后重启编译器,点击菜单栏工具——选项,选择编译ts文件
  4. 在你的项目上右键点击——配置——Enable TypeScript Builder,之后你再保存
  5. .ts文件时会自动保存在当前目录编译出对应的.js文件
数据类型

布尔类型(boolean)

数字类型(number)

字符串类型(string)

1
var str:string = 'hello';

数组类型(array)

1
2
var arr:Array<number> = [11,22,33];  //全是数字的数组
var arr:number[] = [11,22,33];

元组类型(tuple)

1
2
//元组类型属于数组类型用于给数组中每个位置指定类型
let arr:[number,string] = [123,'this is ts'];

枚举类型(enum)

1
2
3
4
5
6
7
8
9
10
enum 枚举名{
标识符[=整型常数],
标识符[=整型常数],
...
标识符[=整型常数],
};
enum Flag { success=1,error=2 };
let s:Flag = Flag.success;
console.log(s); //1
//如果标识符没有赋值,它的值就是下标。

任意类型(any)

null 和 undefined

void类型

1
2
3
4
//一般用于定义方法没有返回值
function run():void{
console.log('ksdkl');
}

never类型

  • never类型是其他类型(包括null和undefined)的子类型,代表从不会出现的值。这意味着声明never的变量只能被never类型所赋值。
函数定义
1
2
3
4
5
6
7
function run():string{
//必须返回string类型的值
}
//匿名函数
let fun2 = function():number{
//返回数字类型的值
}

es5里面方法的实参和形参可以不一样,但是ts中必须一样,如果不一样就需要配置可选参数。(加个 ? )

1
2
3
4
5
6
7
8
function getInfo(name:string,age?:number):string{
if(age){
return `${name} --- ${age}`;
}else{
return `${name} --- 年龄保密`
}
}
alert(getInfo('zhangsan')); //zhangsan --- 年龄保密
ts的重载
  • java中的方法的重载,重载指的是两个或两个以上同名函数,但他们的参数不一样,这时会出现函数重载的情况。
1
2
3
4
5
6
7
8
9
function getInfo(name:string):string;
function getInfo(age:number):string;
function getInfo(str:any):any{
if(typeof str === 'string'){
return "我叫:" + str;
}else{
return "我的年龄是" + str;
}
}
对象继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//es5的类
function Person(){
this.name = '张三';
this.age = 20;
this.run = function(){
alert(this.name);
}
}
Person.prototype.sex = '男';
Person.prototype.work = function(){
alert(this.name);
}
//web类继承Person类 原型链 + 对象冒充的组合继承模式
function Web(){
Person.call(this); //对象冒充实现继承
}
let w = new Web();
w.run(); //对象冒充可以继承构造函数里面的属性和方法
w.work(); //报错,对象冒充不可以继承原型链上的属性和方法

function Web(){}
Web.prototype = new Person(); //原型链实现继承
let w = new Web();
//原型链实现继承:可以继承构造函数里面的属性和方法,也可以继承原型链上的属性和方法。
1
2
3
4
5
6
7
8
9
10
11
12
//es6的类
class Person{
name:string; //属性 前面省略了public关键字
constructor(a:string){
this.name = n;
}
run():void{
alert(this.name);
}
}
let p = new Person('张三');
p.run();
ts接口
  • 接口的作用:在面向对象编程中,接口是一种规范的定义,它定义了行为和动作的规范
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//封装请求的接口
interface Config{
type:string;
url: string;
data?: string;
dataType: string;
}
function ajax(config:Config){
let xml = new XMLHttpResquest();
xhr.open(config.type,config.url,true); //true表示异步请求
xhr.send(config.data);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
console.log('success');
if(config.dataType == 'json'){
JSON.parse(xhr.responseText);
}else{
console.log(xhr.responseText);
}
}
}
}

ajax({
type: 'get',
data: 'name=zhangsan',
url: 'http://a.itying.com/api/productlist',
dataType: 'json'
})

函数类型接口

  • 对方法传入的参数以及返回值进行约束。
1
2
3
4
5
6
7
8
//加密的函数类型接口
interface encrypt{
(key:string,value:string):string;
}
let md5:encrypt = function(key:string,value:string):string{
return key + value;
}
console.log(md5('name','zhangsan'));
ts的实现和继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface Animal{
eat():void;
}
interface Person extends Animal{
work():void;
}
class Web implements Person{
public name:string;
constructor(name:string){
this.name = name;
}
eat(){}
work(){}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
//web继承programmer,实现person
class Programmer{
public name:string;
constructor(name:string){
this.name = name;
}
coding(code:string){}
}
class Web extends Programmer implements Person{
constructor(name:string){}
eat(){}
work(){}
}
ts泛型
  • 泛型:在软件工程中,我们不仅要创建一致的良好的API,也要考虑其可重用性,组件不仅能够支持大哥钱的数据类型,同时也能能支持未来的数据类型,这在创建大型系统时为你提供灵活的功能。
  • 在像C#和java这样的语言中,可以使用泛型来创建可重用地组件,一个组件支持多种类型的数据,这样用户就可以以自己的数据来使用组件。
  • 泛型就是解决类 接口 方法的复用性,以及对不特定数据类型的支持。
1
2
3
4
5
6
7
8
9
//使用any相当于放弃了数据类型检查
function getData(value:any):any{
return value;
}
//T表示泛型,具体什么类型是调用这个方法时决定的,可支持不特定类型的数据类型。可支持传入参数与返回参数的类型一致。
function getData<T>(value:T):T{
return value;
}
getDate<number>(123);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//操作数据库的泛型类
class Mysql<T>{
add(info:T):boolean{
return true;
}
}
class ArticleCate{
title: string|undefined;
desc: string|undefined;
status: number|undefined;
constructor(params:{
title: string|undefined;
desc: string|undefined;
status?: number|undefined;
}){
this.title = params.title
this.deac = params.desc;
this.status = params.status;
}
}
var a = new ArticleCate({
title: '分类',
desc: '111',
status: 1
})
//类当作参数的泛型类
var Db = new MySqlDb<ArticleCate>();
Db.add(a);

jquery

jquery对象是一个包含所有匹配的dom元素的伪数组对象。

js 加载时间线

1、创建document对象,开始解析web页面。创建HTMLHtmlElement对象,添加到document中。这个阶段document.readyState = ‘loading’;

2、遇到link外部css,创建线程加载,并继续解析文档。并发;

3、遇到script外部js,并且没有设置async、defer,浏览器创建线程加载,并阻塞,等待js加载完成并执行该脚本,然后继续解析文档。js拥有修改dom的能力–>domcument.write;

4、遇到script外部js,并且设置有async、defter,浏览器创建线程加载,并继续解析文档;

  defer属性设置后,表示加载script外部js和解析html页面是异步,并且等到html解析完成再执行js解析后的代码;

  async属性设置后,表示加载script外部js和解析html页面是异步,但是当js解析完成,立刻执行它,此时html解析是被阻塞的;

document.createElement(‘script’)的方式动态插入script元素来模拟async属性,实现脚本异步加载和执行;

5、遇到img等,浏览器创建线程加载,并继续解析文档。并发;

6、当文档解析完成,document.readyState = ‘interactive’;

7、文档解析完成后,所有设置有defer的脚本会按照顺序执行(注意与async的不同);

8、document对象触发DOMContentLoaded事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段;

9、当所有async的脚本加载完成并执行后、img等加载完成后,document.readyState = ‘complete’,window对象触发load事件;

10、从此,以异步响应方式处理用户输入、网络事件等。

jQeury

CDN的全称是Content Delivery Network,即内容分发网络。CDN是构建在网络上的内容分发网络,依靠部署在各边缘服务器,通过中心平台的负载均衡,内容分发,调度等功能模块,使用户就近获取所需的内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术在于内容存储和分发技术。

使用Google的CDN

src=”http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"

使用Microsoft的CDN

src=”http://ajax.microsoft.com/ajax/jquery/jquery-1.4.mim.js"

如果您不希望下载并存放 jQuery,那么也可以通过 CDN(内容分发网络) 引用它。

百度、又拍云、新浪、谷歌和微软的服务器都存有 jQuery 。

如果你的站点用户是国内的,建议使用百度、又拍云、新浪等国内CDN地址,如果你站点用户是国外的可以使用谷歌和微软。

使用百度,又拍云,新浪,谷歌或微软的jQuery的一大优势:

当用户在访问其他站点时,已经从百度,又拍云,新浪,谷歌或1微软加载过jQuery,所以当他们访问你的站点时,会从缓存中加载jQuery,这样就减少了加载时间。同时,大多数CDN都可以确保当用户向其请求文件时,会从离用户最近的服务器上访问响应,这样也可以提高加载速度

$(document).ready(function(){//jQuery代码});

这是为了防止文档未完全加载之前就执行jQuery代码,可能会失败

元素 元素
语法 描述
$(“*”) 选取所有元素
$(this) 选取当前 HTML 元素
$(“p.intro”) 选取 class 为 intro 的

元素

$(“p:first”) 选取第一个

元素

$(“ul li:first”) 选取第一个
    元素的第一个
  • 元素
$(“ul li:first-child”) 选取每个
    元素的第一个
  • 元素
$(“[href]”) 选取带有 href 属性的元素
$(“a[target=’_blank’]”) 选取所有 target 属性值等于 “_blank” 的 元素
$(“a[target!=’_blank’]”) 选取所有 target 属性值不等于 “_blank” 的 元素
$(“:button”) 选取所有 type=”button” 的 元素 和
$(“tr:even”) 选取偶数位置的
$(“tr:odd”) 选取奇数位置的

常见 DOM 事件:

鼠标事件 键盘事件 表单事件 文档/窗口事件
click keypress submit load
dblclick keydown change resize
mouseenter keyup focus scroll
mouseleave blur unload

基本行为

  • length:包含dom元素个数
  • [index]/get(index):得到对应位置的DOM元素
  • each():遍历包含所有的DOM元素
  • index():得到所在兄弟元素中的下标
过滤器
  • 多个过滤器不是同时执行的,而是依次执行的。

    $(‘li:gt(0):lt(3)’).css(‘background’,’red’) 下标是 1 2 3变底色

    $(‘li:lt(3):gt(0)’).css(‘background’,’red’) 下标是1 2 变底色

mouseover与mouseenter区别
  • mouseover:在移入子元素时才会触发,对应mouseout
  • mouseenter:只在移入当前元素才触发,对应mouseleave
  • hover()使用的是mouseenter与mouseleave

事件委托(委派/代理)

  • 将多个元素(li)的事件监听委托给父辈元素上(ul)处理。
  • 监听回调是加在父辈元素上
  • 当操作任何一个子元素时(li),事件会冒泡到父辈元素上(ul)
  • 父辈元素不会直接处理事件,而是通过event.target得到发生事件的子元素(li),通过这个子元素调用事件回调函数。
  • $(‘ul’).delegate(‘li’,’click’,function(){})
  • 委托2方
    • 委托方:业主 li
    • 被委托方 中介 ul
  • 好处
    • 新添加的子元素自动有事件响应处理。
    • 减少事件监听的数量 : n==>1
  • API
    • 设置事件委托:$(parentSelector).delegate(childrenSelector,eventName,callback)
    • 移出事件委托:$(parentSlector).undelegate(eventName)

比较keypress、keydown与keyup

  • keydown:在键盘上按下某键时发生,一直按着则会不断触发(opera浏览器除外),它返回的是键盘代码;
  • keypress:在键盘上按下一个按键,并产生一个字符时发生, 返回ASCII码。注意: shift、alt、ctrl等键按下并不会产生字符,所以监听无效,换句话说,只有按下能在屏幕上输出字符的按键时keypress事件才会触发。若一直按着某按键则会不断触发。
  • keyup:用户松开某一个按键时触发,与keydown相对,返回键盘代码.

$(selector).hide(speed,callback);
$(selector).show(speed,callback);

$(selector).toggle(speed,callback); //切换hide()和show()方法

可选的 speed 参数规定隐藏/显示的速度,可以取以下值:”slow”、”fast” 或毫秒。

可选的 callback 参数是 toggle() 方法完成后所执行的函数名称。

可选的 callback 参数,具有以下三点说明:

  1. $(selector)选中的元素的个数为n个,则callback函数会执行n次
  2. callback函数名后加括号,会立刻执行函数体,而不是等到显示/隐藏完成后才执行
  3. callback既可以是函数名,也可以是匿名函数

在在jQuery中可以通过四个方法来实现元素的淡入淡出,这四个方法分别是:fadeIn()、fadeOut()、fadeToggle() 以及 fadeTo()

$(document).ready(function(){
$(“button”).click(function(){
$(“#div1”).fadeIn();
$(“#div2”).fadeIn(“slow”);
$(“#div3”).fadeIn(3000);
});
});

jQuery fadeTo() 方法允许渐变为给定的不透明度(值介于 0 与 1 之间)。

$(selector).fadeTo(speed,opacity,callback);

jQuery slideDown() 方法用于向下滑动元素。

$(selector).slideDown(speed,callback);

jQuery slideToggle() 方法

jQuery slideToggle() 方法可以在 slideDown() 与 slideUp() 方法之间进行切换。

如果元素向下滑动,则 slideToggle() 可向上滑动它们。

如果元素向上滑动,则 slideToggle() 可向下滑动它们。

$(selector).animate({params},speed,callback);

必需的 params 参数定义形成动画的 CSS 属性。

可选的 speed 参数规定效果的时长。它可以取以下值:”slow”、”fast” 或毫秒。

可选的 callback 参数是动画完成后所执行的函数名称。

默认情况下,所有的 HTML 元素有一个静态的位置,且是不可移动的。 如果需要改变为,我们需要将元素的 position 属性设置为 relative, fixed, 或 absolute!

可以用 animate() 方法来操作所有 CSS 属性吗?
是的,几乎可以!不过,需要记住一件重要的事情:当使用 animate() 时,必须使用 Camel 标记法书写所有的属性名,比如,必须使用 paddingLeft 而不是 padding-left,使用 marginRight 而不是 margin-right,等等。

jQuery stop() 方法用于停止动画或效果,在它们完成之前。

stop() 方法适用于所有 jQuery 效果函数,包括滑动、淡入淡出和自定义动画。

$(selector).stop(stopAll,goToEnd);

可选的 stopAll 参数规定是否应该清除动画队列。默认是 false,即仅停止活动的动画,允许任何排入队列的动画向后执行。

可选的 goToEnd 参数规定是否立即完成当前动画。默认是 false。

因此,默认地,stop() 会清除在被选元素上指定的当前动画。

三个简单实用的用于 DOM 操作的 jQuery 方法:

  • text() - 设置或返回所选元素的文本内容
  • html() - 设置或返回所选元素的内容(包括 HTML 标记)
  • val() - 设置或返回表单字段的值

jQuery attr() 方法用于获取属性值。

添加新的 HTML 内容

我们将学习用于添加新内容的四个 jQuery 方法:

  • append() - 在被选元素内部的结尾插入指定内容

  • prepend() - 在被选元素内部的开头插入指定内容

  • after() - 在被选元素之后插入内容

  • before() - 在被选元素之前插入内容

    $(“img”).after(“在后面添加文本”);

$(“img”).before(“在前面添加文本”);

提示:在jQuery中,append/prepend 是在选择元素内部嵌入,而after/before 是在元素外面追加。

删除元素/内容

如需删除元素和内容,一般可使用以下两个 jQuery 方法:

  • remove() - 删除被选元素(及其子元素)
  • empty() - 从被选元素中删除子元素

jQuery 操作 CSS

jQuery 拥有若干进行 CSS 操作的方法。我们将学习下面这些:

  • addClass() - 向被选元素添加一个或多个类
  • removeClass() - 从被选元素删除一个或多个类
  • toggleClass() - 对被选元素进行添加/删除类的切换操作
  • css() - 设置或返回样式属性

设置 CSS 属性

如需设置指定的 CSS 属性,请使用如下语法:

css({“propertyname“:”value“,”propertyname“:”value“,…});

jQuery 提供多个处理尺寸的重要方法:

jQuery Dimensions

向上遍历 DOM 树

  • parent()
    • parent() 方法返回被选元素的直接父元素。
  • parents()
    • parents() 方法返回被选元素的所有祖先元素,它一路向上直到文档的根元素 ()。
  • parentsUntil()
    • parentsUntil() 方法返回介于两个给定元素之间的所有祖先元素。
    • 返回介于
      元素之间的所有祖先元素: $(“span”).parentsUntil(“div”);

向下遍历 DOM 树

下面是两个用于向下遍历 DOM 树的 jQuery 方法:

在 DOM 树中水平遍历

有许多有用的方法让我们在 DOM 树进行水平遍历:

  • siblings():返回被选元素的所有同胞元素
  • next():返回被选元素的下一个同胞元素
  • nextAll():返回被选元素的所有跟随的同胞元素
  • nextUntil():返回介于两个给定参数之间的所有跟随的同胞元素
  • prev()
  • prevAll()
  • prevUntil()

缩小搜索元素的范围

三个最基本的过滤方法是:first(), last() 和 eq(),它们允许您基于其在一组元素中的位置来选择一个特定的元素。

其他过滤方法,比如 filter() 和 not() 允许您选取匹配或不匹配某项指定标准的元素。

first():返回被选元素的首个元素

last():返回被选元素的最后一个元素

eq() 方法返回被选元素中带有指定索引号的元素。

索引号从 0 开始,因此首个元素的索引号是 0 而不是 1。

filter() 方法允许您规定一个标准。不匹配这个标准的元素会被从集合中删除,匹配的元素会被返回。

jQuery AJAX

  • AJAX是与服务器交换数据的技术,它在不重载全部页面的情况下,实现对部分页面的更新
  • AJAX=异步JavaScript和XML(Asynchronous JavaScript and XML),通过AJAX方法,你可以使用HTTP Get和HTTP Post从远程服务器上请求文本,HTML,XML,JSON,同时你可把这些外部数据直接载入网页的被选元素中

作为一般函数调用$(param)

  1. 参数为函数:当DOM加载完成后,执行此回调函数。
  2. 参数为选择器字符串:查找所有匹配的标签,并把它们封装成jquery对象。
  3. 参数是DOM对象:将dom对象封装成jquery对象。
  4. 参数为html标签字符串(用得最少):创建标签对象并封装成jquery对象。

作为对象使用

  1. $.each():隐式遍历数组
  2. $.trim():去除两端的空格

AJAX

load()

  • load()方法从服务器加载数据,并把返回的数据放入被选元素中
    • $(selector).load(URL,data,callback);
    • 必须的URL参数规定你希望加载的URL
    • 可选的data参数规定与请求一同发送的查询字符串键/值对集合
    • 可选的callback(responseTxt,statusTXT,xhr)参数是load()完成后执行的函数名称,无论AJAX请求是否成功,一旦请求完成后,函数callback立即被触发
    • responseTxt–包含调用成功时的结果内容 statusTXT—包含调用的状态 xhr——包含XMLHttpRequest对象

$.get(URL,callback)和post()

  • 两者都能通过HTTP或POST请求从服务器请求数据
  • get是从指定的资源请求数据,基本用于从服务器获得数据,可能返回缓存数据
  • post向指定的资源提交要处理的数据,可用于从服务器获取数据。不过,post方法不会缓存数据,并且常用于连同请求一起发送数据

$.noConflict()方法

  • 解决在页面同时使用jQuery和其他框架(在同一个页面加载多个jQuery实例,尤其是不同版本的jQuery)
  • noConflict()会释放对$($是jQuery的简写)

$(selector).bind(event,data,function,map)

参数 描述
event 必需。规定添加到元素的一个或多个事件。 由空格分隔多个事件值。必须是有效的事件。
data 可选。规定传递到函数的额外数据。
function 必需。规定当事件发生时运行的函数。
map 规定事件映射 ({event:function, event:function, …}),包含要添加到元素的一个或多个事件,以及当事件发生时运行的函数。
  • bind() 方法向被选元素添加一个或多个事件处理程序,以及当事件发生时运行的函数。

  • 自 jQuery 版本 1.7 起,on() 方法是向被选元素添加事件处理程序的首选方法。

$(selector).delegate(childSelector,event,data,function)

参数 描述
childSelector 必需。规定要添加事件处理程序的一个或多个子元素。
event 必需。规定添加到元素的一个或多个事件。 由空格分隔多个事件值。必须是有效的事件。
data 可选。规定传递到函数的额外数据。
function 必需。规定当事件发生时运行的函数。

原生js与jQuery的区别

1.原生JS与jQuery入口函数的加载模式不同

  • 原生JS会等到DOM元素和图片都加载完毕再执行
  • jQuery只是等DOM加载完毕之后就执行

2.覆盖问题

  • 原生js如果有多个入口函数,后面编写的会覆盖前面的
  • jQuery有多个入口函数时不会相互覆盖,都会执行

3.多个框架时的冲突问题

  • 解决方法:释放$的使用权

iQuery.noConflict();

注意点:释放操作必须在编写其他jQuery代码之前编写

​ 释放之后就不能再使用$改为jQuery

  • 自定义访问符号

var nj = jQuery.noConflict();

nj(function (){ });

4.遍历数组

  • js中用forEach()只能遍历数组,不能遍历伪数组,参数位置不同

    arr.forEach(function (value,index){ });

  • 利用jQuery的Each()静态方法遍历数组/伪数组,参数位置不同

    $.each(arr,function (index,value){ });//遍历数组

    $.each(obj,function (index,value){ });//遍历伪数组

jQuery中的each()静态方法和map()静态方法的区别:

  • each()静态方法默认的返回值就是遍历谁就返回谁,不支持在回调函数中对数组进行处理
  • map()静态方法默认的返回值是一个空数组,可通过回调函数进行处理,然后生成一个新的数组返回

复习jquery

  • DOM中的顶级对象:document ——页面中的顶级对象
  • BOM中的顶级对象:window
  • jQuery的顶级对象:jQuery——$
$与$()的区别
  • $是一个函数对象,包含很多静态方法,这种方法,一般的js也是可以使用。
  • $()是调用这个函数对象的一个实例,返回一个对象,一般是由$对象拓展的对象属性。
1
2
3
4
5
$().css();
$().html();

$.trim();
$.proxy();
$常见属性方法
1
2
3
4
5
6
7
8
9
10
11
trim()			去除前后格
makeArray() 类数组转为真数组
inArray() 数组版indexOf
merge() 合并数组
grep() 过滤新数组
map() 映射新数组
guid 唯一标识符
proxy() 改this指向
access() 多功能操作值(内部)
now() 当前时间
swap() CSS交换(内部)

js动画篇

动画

一. @keyframes规则是创建动画,它指定一个css样式和动画将逐步从当前样式更改为新的样式

当在keyframes创建动画时,把他绑定到一个选择器,否则动画不会有任何效果,至少指定这两个动画属性

  • 规定动画名称
  • 规定动画时长
  • animation: myfirst 5s;

二 . animation属性

语法:

animation: name duration time-function delay iteration-count direction;

描述
animation-name 规定需要绑定到选择器的keyframe名称

animation-duration 规定完成动画所花费的时间,以s/ms记

animation-time-function 规定动画的速度曲线

animation-iteration-count 规定动画应该播放的次数

animation-direction 规定是否应该轮流方向播放动画

注意:请始终规定animation-duration属性,否则时长为0,就不会播放动画。

三 . animation-delay属性

1.定义动画什么时候开始(s/ms)
  • 可为负值,-2s使动画马上开始,但跳过2s进入动画

四 . animation-direction属性

1.animation-direction:属性控制如何在reversealternate周期播放动画。

如果 animation-direction 值是 “alternate”,则动画会在奇数次数(1、3、5 等等)正常播放,而在偶数次数(2、4、6 等等)向后播放。

注释:如果把动画设置为只播放一次,则该属性没有效果。

  • 属性值
描述
normal 以正常的方式播放动画
reverse 以相反方向播放动画
alternate 播放动画作为正常每奇数时间(1,3,5等)和反方向每偶数时间(2,4,6,等…)
alternate-reverse 在每个奇数时间(1,3,5等)在相反方向上播放动画,并且在每个偶数时间(2,4,6等等)的正常方向上播放动画

五 . animation-duration属性

1.定义完成一个动画需要的时间s/ms

animation-duration:time;

六 . animation-fill-mode属性

1.设置样式以在动画不播放时应用元素
  • animation-fill-mode:none | forwards | backwards |both |initial |inherit ;

    描述
    none 默认值,无样式

    forwards 动画结束后,使用元素的结束属性值

    backwards 使用元素的起始值

    both 动画遵循向前向后的规则

七 . animation-iteration-count属性

1 . 定义动画应该播放几次
描述
n 定义播放动画多少次。 默认值为1
infinite 指定动画应该播放无限次(永远)

八 . animation-name属性

1. animation-name属性为@keyframes动画规定名称
描述
keyframename 规定需要绑定到选择器的 keyframe 的名称。
none 规定无动画效果(可用于覆盖来自级联的动画)。

九 . animation-play-state属性

1.设置是否运行或者暂停动画

你可以在js中使用该属性,这样就可以在播放过程中暂停动画

animation-play-state:paused | running;

十 . animation-timing-function属性

1 . 指定动画速度曲线

​ 速度曲线定义动画从一套CSS样式变为另一套所用的时间,速度曲线用于使变化更为平滑

​ animation-timing-function : linear | ease | ease-in | ease-out | cubic-bezier(n,n,n,n);

描述
linear 动画从开始到结束具有相同的速度。
ease 动画有一个缓慢的开始,然后快,结束慢。
ease-in 动画有一个缓慢的开始。
ease-out 动画结束缓慢。
ease-in-out 动画具有缓慢的开始和慢的结束。
cubic-bezier(n,n,n,n) 在立方贝塞尔函数中定义速度函数。 可能的值是从0到1的数字值。

转换transform

一 . 2D转换

1.旋转transform : rotate(30deg);

在给定度数顺时针旋转的元素。负值表示逆时针deg表示度数。

2.移动 transform:translate(50px,100px);

往左往上为正

3.缩放 transform:scale(2,4);

scale(2,4)转变宽度为原来的大小的2倍,和其原始大小4倍的高度。

4.倾斜 transform:skew(30deg,20deg);

包含两个参数值,分别表示X轴和Y轴倾斜的角度,如果第二个参数为空,则默认为0,参数为负表示向相反方向倾斜。

  • skewX( );表示只在X轴(水平方向)倾斜。
  • skewY( );表示只在Y轴(垂直方向)倾斜。
  • skew(30deg,20deg) 是元素在X轴和Y轴上倾斜20度30度。

总的语法

transform: none|transform-functions;

描述
none 定义不进行转换。
matrix(n,n,n,n,n,n) 定义 2D 转换,使用六个值的矩阵。
matrix3d(n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n) 定义 3D 转换,使用 16 个值的 4x4 矩阵。
translate(x,y) 定义 2D 转换。
translate3d(x,y,z) 定义 3D 转换。
translateX(x) 定义转换,只是用 X 轴的值。
translateY(y) 定义转换,只是用 Y 轴的值。
translateZ(z) 定义 3D 转换,只是用 Z 轴的值。
scale(x[,y]?) 定义 2D 缩放转换。
scale3d(x,y,z) 定义 3D 缩放转换。
scaleX(x) 通过设置 X 轴的值来定义缩放转换。
scaleY(y) 通过设置 Y 轴的值来定义缩放转换。
scaleZ(z) 通过设置 Z 轴的值来定义 3D 缩放转换。
rotate(angle) 定义 2D 旋转,在参数中规定角度。
rotate3d(x,y,z,angle) 定义 3D 旋转。
rotateX(angle) 定义沿着 X 轴的 3D 旋转。
rotateY(angle) 定义沿着 Y 轴的 3D 旋转。
rotateZ(angle) 定义沿着 Z 轴的 3D 旋转。
skew(x-angle,y-angle) 定义沿着 X 和 Y 轴的 2D 倾斜转换。
skewX(angle) 定义沿着 X 轴的 2D 倾斜转换。
skewY(angle) 定义沿着 Y 轴的 2D 倾斜转换。
perspective(n) 为 3D 转换元素定义透视视图。

二 . transform-origin

1.transform-Origin属性允许您更改转换元素的位置。

2D转换元素可以改变元素的X和Y轴。 3D转换元素,还可以更改元素的Z轴。

transform-origin: x-axis y-axis z-axis;

描述
x-axis 定义视图被置于 X 轴的何处。left center right length %
y-axis 定义视图被置于 Y 轴的何处。可能的值:top center bottom length %
z-axis 定义视图被置于 Z 轴的何处。可能的值:length
2.transform-style属性指定嵌套元素是怎么在三维空间中呈现
  • transform-style: flat | preserve-3d;

    描述
    flat 子元素将不保留其 3D 位置。
    preserve-3d 子元素将保留其 3D 位置。

让转换的子元素保留3D转换:

div
{
transform: rotateY(60deg);
transform-style: preserve-3d;
-webkit-transform: rotateY(60deg); /* Safari and Chrome /
-webkit-transform-style: preserve-3d; /
Safari and Chrome */
}

transition属性过渡

transition 属性是一个简写属性,用于设置四个过渡属性:

  • transition-property
  • transition-duration
  • transition-timing-function
  • transition-delay
1
transition: property duration timing-function delay;
描述
transition-property 规定设置过渡效果的 CSS 属性的名称。
transition-duration 规定完成过渡效果需要多少秒或毫秒。
transition-timing-function 规定速度效果的速度曲线。
transition-delay 定义过渡效果何时开始。
  • transition-property属性指定css属性的nametransition效果(transition效果时将会启动指定的css属性的变化。

  • 一个转场效果通常发生在当鼠标悬停在一个元素上

  • 始终指定transition-duration属性,否则持续时间为0,transition不会有效果默认值是all,多项改变要添加多个样式的变换效果,添加的属性由逗号分隔

    transition-property: none|all| property;

    描述
    none 没有属性会获得过渡效果。
    all 所有属性都将获得过渡效果。
    property 定义应用过渡效果的 CSS 属性名称列表,列表以逗号分隔。

三 . 透视3D属性perspective

多少像素的3D元素是从视图的perspective属性定义。这个属性允许你改变3D元素是怎样查看透视图。perspective 属性只影响 3D 转换元素;定义时的perspective属性,它是一个元素的子元素,透视图,而不是元素本身。

perspective: number|none;

描述
number 元素距离视图的距离,以像素计。
none 默认值。与 0 相同。不设置透视。

一般跟perspective-origin属性配合使用,默认值都是50%

四 。 backface-visibility属性

1. backface-visibility属性定义当元素不面向屏幕时是否可见,默认可见

如果在旋转元素不希望看到其背面时,该属性很有用。

1
backface-visibility: visible|hidden;
描述
visible 默认值。 背面是可见的。
hidden 背面是不可见的。

五 . 盒阴影box-shadow

box-shadow : 向左偏移量 向下偏移量 阴影半径 颜色;

注意:向右向下为正

六 . 边界图片border-image

border-image属性允许你指定一个图片作为边框!用于创建上文边框的原始图像

border-image:url(border.png) 30 30 round;

速记属性

border-image:source slice width outset repeat;

描述
border-image-source 用于指定要用于绘制边框的图像的位置
border-image-slice 图像边界向内偏移
border-image-width 图像边界的宽度
border-image-outset 用于指定在边框外部绘制 border-image-area 的量
border-image-repeat 这个例子演示了如何创建一个border-image 属性的按钮。
  • border-image-source: url(border.png);
说明
none 没有图像被使用
image 边框使用图像的路径
  • 1
    border-image-outset: length|number(代表对应的border-width的倍数);

    注释:border-image-outset 属性规定边框图像超出边框盒的量。在上、右、下、左侧。如果忽略第四个值,则与第二个值相同。如果省略第三个值,则与第一个值相同。如果省略第二个值,则与第一个值相同。不允许任何负值作为 border-image-outset 值。

  • 1
    border-image-width: number|%|auto;

    注意:

    border-image -width的4个值指定用于把border图像区域分为九个部分。他们代表上,右,底部,左,两侧向内距离。如果第四个值被省略,它和第二个是相同的。如果也省略了第三个,它和第一个是相同的。如果也省略了第二个,它和第一个是相同的。负值是不允许的。

    描述
    number 代表对应的 border-width 的倍数。
    % 参考边框图像区域的尺寸:区域的高度影响水平偏移,宽度影响垂直偏移。
    auto 如果规定该属性,则宽度为对应的图像切片的固有宽度。

七 . border-collapse 属性

设置表格的边框是否被合并为一个单一的边框

说明
collapse 如果可能,边框会合并为一个单一的边框。会忽略 border-spacing 和 empty-cells 属性
separate 默认值。边框会被分开。不会忽略 border-spacing 和 empty-cells 属性
inherit 规定应该从父元素继承 border-collapse 属性的值

八 .border-color:红,绿,蓝,粉红色;

  • 上边框是红色
  • 右边框是绿色
  • 底部边框是蓝
  • 左边框是粉红色

border-color:红,绿,蓝;

  • 上边框是红色
  • 左,右边框是绿色
  • 底部边框是蓝

border-color:红,绿;

  • 顶部和底部边框是红色
  • 左右边框是绿色

border-color:红色;

  • 所有四个边框是红色

请始终把 border-style 属性声明到 border-color 属性之前。元素必须在您改变其颜色之前获得边框。

说明
color 指定背景颜色。在CSS颜色值查找颜色值的完整列表
transparent 指定边框的颜色应该是透明的。这是默认
inherit 指定边框的颜色,应该从父元素继承

颜色渐变

一 . 线性渐变(Linear Gradients)

  • background: linear-gradient(direction, color-stop1, color-stop2, …);
    • background: -webkit-linear-gradient(red, blue); /* Safari */
    • background: -o-linear-gradient(red, blue); /* Opera **/ *
    • background: -moz-linear-gradient(red, blue); /* Firefox */
    • background: linear-gradient(red, blue); /* 标准的语法 */

二 . 径向渐变(Radial Gradients)

  • 默认情况下,渐变的中心是 center(表示在中心点),渐变的形状是 ellipse(表示椭圆形),渐变的大小是 farthest-corner(表示到最远的角落)。

  • background: radial-gradient(center, shape size, start-color, …, last-color);

  • 径向渐变 - 颜色结点不均匀分布

    • background: -webkit-radial-gradient(red 5%, green 15%, blue 60%);
  • shape 参数定义了形状。它可以是值 circle 或 ellipse。其中,circle 表示圆形,ellipse 表示椭圆形。默认值是 ellipse。

    不同尺寸大小关键字的使用

    size 参数定义了渐变的大小。它可以是以下四个值:

    • closest-side
    • farthest-side
    • closest-corner
    • farthest-corner

三 . 透明度transparency

  • 用于创建减弱变淡的效果;为了添加透明度,我们使用 rgba() 函数来定义颜色结点。rgba() 函数中的最后一个参数可以是从 0 到 1 的值,它定义了颜色的透明度:0 表示完全透明,1 表示完全不透明。
  • repeating-linear-gradient() 函数用于重复线性渐变:

js精研

一 . 基础补充

1.值,变量和类型

  • typeof undefined;//“undefined”

  • js是基于32位整数的

  • 以下两种情况,js会自动将数值转为科学计数法

    • 小数点前的数字多于21位
    • 小数点后的0多于5个
  • 在js内部,实际存在两个0:+0和-0,他们是等价的

  • 当js在算数运算时发生溢出(overflow,结果是Infinity),下溢(underflow,结果是-Infinity)或被0整除时不会报错

  • Infinity大于一切数值(除了NaN),-Infinity小于一切数值(除了NaN)。isFinite函数返回一个布尔值,检查某个值是不是正常数值,而不是Infinity。

  • 注意:0除以0是无意义的,会返回NaN

    • isNaN判断一个值是否为NaN,它只对数值有效,若传入其他值,会被先转成数值。比如,传入字符串的时候,字符串会被先转成NaN,所以最后返回true,这一点要特别引起注意。也就是说,isNaN为true时,有可能不是NaN,而不是一个字符串
    • 使用isNaN前,最好判断一下数据类型 typeof value===’number’&& isNaN(value)
    • 判断NaN更可靠的方法是利用NaN在js中唯一不等于自身的值这个特点进行判断 value!==value
  • 字符串可以被视为字符数组,因此可以使用数组的方括号运算符,用来返回某个位置的字符(位置编号从0开始)。

    • length属性返回字符串的长度,该属性也是无法改变的。

    • 如果方括号中的数字超过字符串的长度,或者方括号中根本不是数字,则返回undefined。

    • 注意:字符串与数组仅仅是相似而已。字符串是无法改变字符串之中的单个字符。

      var a = ‘hello’;

      delete s[0];

      s // “hello”

      s[0] = ‘a’;

      s // “hello”

  • 尽管null和undefined是不同的,但它们都表示“值的空缺”,两者往往可以互换。当用相等运算符“==”来比较两者时,会返回true。(要使用严格相等运算符“===”来区分它们)

  • 如果JavaScript预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。转换规则是除了下面六个值被转为false,其他值都视为true。

    undefined
    null
    false
    0
    NaN
    “”或’’(空字符串)

  • 如果一个变量没有声明就直接使用,JavaScript会报错,告诉你变量未定义。

  • 声明提前(变量提升)

    • JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就是声明提前(变量提升,hoisting)。
    • 变量提升只对var命令声明的变量有效,如果一个变量不是用var命令声明的,就不会发生变量提升。
  • typeof运算符对未声明的变量运算,不会报错,输出值也是“undefined”,故不能区分该值是否已声明,但是其他运算符对未声明变量进行运算会报错

  • 对于浮点字面量的有趣之处在于,用它进行计算之前,真正存储的是字符串。任何值在输出时一般都会转化成字符串输出

  • ECMAScript默认把具有6个或6个以上前导0的浮点数转化成科学计数法。也可以用64位IEEE 754形式存储浮点值,这意味着十进制最多可以有17个十进制位,17位之后的值将被裁剪,从而造成较小的误差

  • 当计算生成的数大于 Number.MAX_VALUE 时,它将被赋予值Number.POSITIVE_INFINITY,意味着不再有数字值。同样,生成的数值小于Number.MIN_VALUE 的计算也会被赋予值Number.NEGATIVE_INFINITY,也意味着不再有数字值。如果计算返回的是无穷大值,那么生成的结果不能再用于其他计算。

2.语句

  • 注意:由于对每个case的匹配操作实际是“===”恒等运算符比较,而不是“==”相等运算符比较,因此,表达式和case的匹配并不会做任何类型转换。

  • 使用while(true)则会创建一个死循环。

  • 标签语句

    • 语句是可以添加标签的,标签是由语句前的标识符和冒号组成:

      label : statement

  • return语句只能在函数体内出现,否则报错。当执行到return语句时,函数终止执行。

  • throw语句:异常是指当发生了某种异常情况或错误时产生的一个信号。

  • with语句:用于临时扩展作用域链

    with ( object ){

    statement

    }

    将object添加到作用域链的头部,然后执行statement,最后把作用域链恢复到原生状态。

    注意:在严格模式中是禁止使用with语句的。

  • debugger语句用来产生一个断点(breakpoint),JavaScript代码的执行会停止在断点的位置。一般用来调试代码。

  • “use strict”

    使用”use strict”指令的目的是说明后续的代码将会解析成严格代码。

3.对象

  • 对象是一个基本数据类型,成员以键值对形式存在

  • 键名:对象的所有键名都是字符串,所以加不加引号都可以。如果键名是数值,会被自动转为字符串。

  • 对象的每一个“键名”又称为“属性”(property),它的“键值”可以是任何数据类型。如果一个属性的值为函数,通常把这个属性称为“方法”,它可以像函数那样调用。

  • 如果键名不符合标识名的条件(比如第一个字符为数字,或者含有空格或运算符),也不是数字,则必须加上引号,否则会报错。

  • 为了避免这种歧义,JavaScript规定,如果行首是大括号,一律解释为语句(即代码块)。如果要解释为表达式(即对象),必须在大括号前加上圆括号。

  • 创建对象

    在JavaScript中,有三种方法创建对象

    1
    2
    3
    对象直接量: var o={};
    关键字new: var o=new Object();
    Object.create()函数: var o=Object.create(null)
  • 对象直接量中的最后一个属性后的逗号可有可无,但是在ie中,如果多了一个逗号,会报错。通过new创建对象

    new运算符创建并初始化一个新对象。关键字new后跟随一个函数调用,这个函数称做构造函数(constructor)。

  • 属性名可以是包含空字符串在内的任意字符串,但对象中不能存在两个同名的属性。

  • 读取对象的属性

    • 有两种方法,一种是使用点运算符(最终还是得先变成方括号),还有一种是使用方括号运算符
    • 数值键名不能使用点运算符(因为会被当成小数点),只能使用方括号运算符。
    • 通过点(.)或方括号([])运算符来获取属性的值时,运算符左侧应当是一个表达式,它返回一个对象。
  • 查看一个对象本身的所有属性,可以使用Object.keys方法,返回一个类数组

    var o = {

    name : ‘a’,

    age : 12

    }

    Object.keys(o) //[‘name’,’age’]

  • 删除属性

    • delete运算符只能删除自有属性,不能删除继承属性。

    • 删除一个不存在的属性,delete不报错,而且返回true。
    • 只有一种情况,delete命令会返回false,那就是该属性存在,且不得删除。

  • 检测属性是否存在于某个对象中

    • 用“!==”来判断一个属性是否是undefined(无法判断属性是否是继承来的)

    • hasOwnPreperty()方法:检测的是自身属性,无关继承来的属性
    • propertyIsEnumerable()方法:只有检测到自有属性且这个属性的可枚举性为true时才返回true
    • in元素符左侧属性名(字符串),右侧是对象。如果对象的自有属性或继承属性中包含这个属性就返回true(无法判断属性是否是继承来的)

  • 对象的三大属性

    • 每个对象都有与之相关的原型(prototype),类(class)和可扩展性(extensible attribute)
    • 将对象作为参数传入Object.getPrototypeOf()可以查询他的原型
    • 检测一个对象是否是另一个对象的原型,可使用isPrototypeOf()方法
  • 序列化对象

    • 对象序列化是指将对象的状态转换为字符串,也可将字符串还原为对象

    • 在js中,提供内置函数JSON.stringify()和JSON.parse()用来序列化和还原js对象

    • NaN,Infinity和-Infinity序列化的结果是null

      var o = {

      name : ‘a’,

      age : 12,

      intro : [false,null,’’]

      }

      s= JSON.stringify(o) // s {“name”:”a”,”age”:12,”intro”:[false,null,””]}

      p=JSON.parse(s) // p是o的深拷贝

    • JSON.stringify()只能序列化对象可枚举的自有属性,对于一个不能序列化的属性来说,在序列化后的输出字符串中会将这个属性省略掉

    • 深拷贝与浅拷贝的区别

      • 浅拷贝只是复制了对象的地址,两个对象指向同一个地址,所以修改其中的值,另一个值都会随之改变

      • 深拷贝是将对象及值复制过来,两个对象修改其中任意值,另一个值不会随之改变,这就是深拷贝(如:JSON.stringify()和JSON.parse(),但是此方法无法复制函数数据类型)

      • 当你需要深拷贝对象中的方法时可使用lodash.js(提高js原生方法性能的js库)中的cloneDeep()方法

        var objA = { “name”: “戈德斯文” };

        var objB =lodash.cloneDeep(objA);

      • 深拷贝首推的方法简单有效,JSON.stringfy()和JSON.parse()即可搞定。但是这种简单粗暴的方法有其局限性。当值为undefinedfunctionsymbol 会在转换过程中被忽略。所以,对象值有这三种的话用这种方法会导致属性丢失。

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        var syb = Symbol('obj');
        var person = {
        name :'tino',
        say: function(){
        console.log('hi');
        },
        ok: syb,
        un: undefined
        }
        var copy = JSON.parse(JSON.stringify(person))
        // copy
        // {name: "tino"}
  • js中对象的可枚举属性和不可枚举属性是由属性的enumerable值决定的。可枚举性决定了这个属性能否被for….in查找遍历到

    • js中的基本包装类的原型属性是不可枚举的,如Object,Array,Number,这些对象的内置属性是不可枚举的
    • 需要注意的是:如果判断的属性存在于Object对象的原型内,不管它是否可枚举都会返回false。
  • 构造函数是用来生成“对象”的函数。一个构造函数可生成多个对象,这些对象都有相同的结构

    • 构造函数的特点:函数体内使用this关键字代表所要生成的对象实例。生成对象时,必须用new命令,构造函数名字的首字母通常大写

    • new命令本身就可以执行构造函数,所以后面的构造函数可带括号可不带

      var c = new Car();

      var c = new Car;

    • 每一个构造函数都有prototype属性

事件机制

事件机制之冒泡、传播、委托

DOM事件流(event flow)存在三个阶段:事件捕获阶段,处于目标阶段,事件冒泡阶段

事件捕获阶段(event capuring)

通俗理解就是,当鼠标点击或触发dom事件时,浏览器会从根节点由外往内进行事件传播,即点击了子元素,如果父元素通过事件捕获注册了对应的事件的话,会先触发父元素绑定的的事件。

事件冒泡(dubbed bubbling)

与事件捕获相反,事件冒泡是从目标元素由内往外进行事件传播,直到根节点。

无论是事件冒泡还是事件捕获,都有一个共同点就是事件传播,她就像一根引线,只有通过引线才能将绑在引线上的鞭炮(事件监听器)引爆,试想一下,如果引线不导火了,那鞭炮就只有一响了!

dom事件标准事件流的触发先后顺序是:先捕获后冒泡,即当触发dom事件时,会进行事件捕获,捕获到事件源后通过事件传播进行事件冒泡。不同浏览器对此有不同的实现,IE10及以下不支持捕获型事件,所以就少了一个时间捕获阶段,IE11,Chrome,Firefox,Safari等浏览器则同时存在。

事件绑定的方法

addEventlistener(event,listener,useCapture)

参数定义:event——(事件名称:如click,不带on)

listener——事件监听函数,

useCapture——是否采用事件捕获进行事件捕获,默认为false,即采用事件冒泡方式。

addEventListener在IE11,Chrome,Firefox,Safari等浏览器都得到支持。

attachEvent(event,listener)

参数定义:event—(事件名称,如onclick,带on),

listener—事件监听函数。

attachEvent主要用于IE浏览器,并且仅在IE10及以下才支持,IE11已经废了这个方法了

事件冒泡例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<style>
#parent{width:200px;height:200px;background:yellow;margin:10px auto;border:1px solid black;}
#children{width:50px;height:50px;background:pink;margin:80px auto;}
</style>
<title>Document</title>
</head>
<body>
<div id="parent">
<div id="children"></div>
</div>
</body>
</html>
<script>
var children = document.getElementById('children');
var parent = document.getElementById('parent');
document.body.addEventListener('click',function(){console.log('body')},false);
parent.addEventListener('click',function(){console.log('parent')},false);
children.addEventListener('click',function(){console.log('children');
//event.stopProparation;
//可停止事件传播},false);
</script>

当点击子盒子时,打印结果依次为children——parent——body

事件触发的顺序是由内到外的,这就是事件冒泡,虽然只点击了子元素,但是他的父元素也会触发相应的事件,其实这也是合理的,因为父元素里面,点击了子元素不就相当于变相的点击了父元素。

若不想触发父元素可停止事件传播只需在子元素中添加event.stopProparation;即可。

事件捕获例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<style>
body{background: green;}
#parent{width:200px;height:200px;background:yellow;margin:10px auto;border:1px solid black;}
#children{width:50px;height:50px;background:pink;margin:80px auto;}
</style>
<title>Document</title>
</head>
<body>
<div id="parent">
<div id="children"></div>
</div>
</body>
</html>
<script>
var children = document.getElementById('children');
var parent = document.getElementById('parent');
document.body.addEventListener('click',function(){console.log('body')},true);
parent.addEventListener('click',function(){console.log('parent')},true);
children.addEventListener('click',function(){console.log('children')},true);
</script>

点击children方块,打印body——parent——childre

点击parent方块,打印body——parent

点击body区域,打印body

事件通过事件捕获的方式注册了click事件,所以在事件捕获阶段就会触发,先是触发最外围注册了事件捕获的body,而后触发事件捕获的parent,最后触发事件源。这就是事件的时间流程。

要求

高质量代码

  • bug暴露
  • 不扩展内置原型,多用this取代构造函数的prototype
  • 使用switch模式增强可读性和健壮性
  • 使用绝对相等或绝对不等,避免隐式类型转换
  • 避免使用eval(),因此方法接受任意的字符串,被执行的代码可能被篡改,有极大的安全隐患。且会污染全局变量
  • 用方括号表示法访问动态属性
  • parseInt()下数值转换,最好指定基数参数,不然,可能以0开头的数据被当成8进制使用

提高性能

(类)数组循环获取值时缓存长度
  • 不足:每次循环时数组的长度都要去获取,会降低代码
  • 若是类数组,需实时查询基本文档(html页面),这意味着每次你访问任何集合的长度,你要实时查询DOM,而DOM操作一般都是比较昂贵的。
  • 解决:把数组长度放在一个变量里;从后往下标为0的数数,因为和0做比较要比和数组长度或是其他不是0的东西作比较更有效率。
for循环遍历数组,for-in循环遍历类数组
遍历属性时使用hasOwnProperty()方法过滤原型上的属性

var的作用

优点
  • 避免创建隐式全局变量:1.函数中未声明就使用变量 2.使用任务链进行部分var声明
  • 可移植性:可在不同主机上使用
缺点
  • 通过var创建的全局变量不可通过delete删除,无var创建的隐式全局变量(并非真正的全局变量,只是全局变量的属性)可通过delete删除

执行层面

代码处理的两个阶段(预解析hoisting)
  • 变量,函数声明,以及正常格式的参数创建,这是一个解析和进入上下文的阶段
  • 代码执行,函数表达式和不合格的标识符(为声明的变量)被创建。

二 . JavaScript对象

  • JavaScript是一种直译式脚本语言,是一种动态类型,弱类型,基于原型的语言,内置支持类型

  • 日常用途
    1. 嵌入动态文本于HTML页面。
    2. 对浏览器事件做出响应。
    3. 读写HTML元素
    4. 在数据被提交到服务器之前验证数据。
    5. 检测访客的浏览器信息。
    6. 控制cookies,包括创建和修改等。
    7. 基于Node.js技术进行服务器端编程。

对象公共属性

1.constructor属性
  • constructor属性返回对创建此对象的函数的引用
  • 函数对象。 返回创建布尔对象的函数原型。=函数.constructor;
2.prototype属性
  • 是您有能力向对象添加属性和方法
  • 当构造一个原型,所有的对应对象默认都添加了属性和方法
  • 每个js对象(除了null)都和另一个对象相关联,即继承另一个对象。另一个对象就是我们熟知的“原型(prototype),每个对象都从原型继承属性。只有null除外,他没有自己的原型对象
  • 通过Object.prototype获得对原型对象的引用,通过对象或构造函数调用创建的对象的原型就是构造函数的prototype属性的值,找不到原型,返回undefined
3.toString()把对象转为字符串并返回结果
  • String=对象.toString()
4.valueOf() 返回对象的原始值

Array=array.valueOf() 不会改变原数组

5.Object.getPrototypeOf()
  • 返回一个对象的原型
6.Object.setPrototypeOf()
  • 为现有对象设置原型,返回一个新对象
  • 接受两个参数,第一个是现有对象,第二个是原型对象
7.Object.create()
  • 用于从原型对象生成新的实例对象,可以替代new命令
  • 它接受一个对象作为参数,返回一个新的对象,后者完全继承前者的属性,即原有对象成为新对象的原型
8.Object.prototype.isPrototypeOf()
  • 判断一个对象是否是另一个对象的原型
  • Object.prototype.isPrototypeOf({}) //true
9.Object.prototype.proto_

_proto__属性(前后各两个下划线)可以改写某个对象的原型对象

10.Object.getPropertyOfNames()
  • 该方法返回一个数组,成员是对象本身的所有属性的键名,不包含的属性键名
11.Object.prototype.hasOwnProperty()
  • 返回一个布尔值,用于判断某个属性定义在对象本身还是在原型链上

1.Array数组对象

  • 数组对象的作用是使用单独的变量名来存储一系列的值
  • length属性是可写的。如果人为设置一个小于当前成员个数的值,该数组的成员会自动减少到length设置的值。
1.concat()连接两个或多个数组
  • 该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本
  • array1.concat(array2,array3,…,arrayX)
2.every()检查所有数组元素,返回boolear
  • 用于检测数组所有元素是否都符合指定条件(通过函数提供),只有所有元素都满足条件才返回true

  • every()不会对空数组进行检测,且不会改变原始数组

  • array.every(function(currentValue,index,arr),thisValue)

    参数 描述
    function(currentValue, index,arr) 必须。函数,数组中的每个元素都会执行这个函数 函数参数: 参数描述currentValue必须。当前元素的值index可选。当期元素的索引值arr可选。当期元素属于的数组对象
    thisValue 可选。对象作为该执行回调时使用,传递给函数,用作 “this” 的值。 如果省略了 thisValue ,”this” 的值为 “undefined”
3.filter()创建所有符合条件元素的数组
  • 创建一个新数组,不会对空数据进行检测,也不会改变原始数组.如果没有符合条件的元素则返回空数组。
  • array.filter(function(currentValue,index,arr),thisValue)
4.indexOf()返回指定字符串值首次出现的位置
  • array.indexOf(item,start)
参数 描述
item 必须。查找的元素。
start 可选的整数参数。规定在字符串中开始检索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略该参数,则将从字符串的首字符开始检索。
  • 返回值为number值,如果没有搜索到则返回-1
  • lastIndexOf() 查找字符串最后出现的位置
5.join() 把数组中的所有元素为一个字符串
  • 元素是通过指定的分隔符进行分隔的

  • string =array.join(separator)

    参数separator是可选的,是指定要使用的分隔符,若省略,默认使用逗号

    返回值是一字符串。该字符串是通过把arrayObject的每个元素转换为字符串,然后把这些字符串连接起来,在两个元素之间插入separator字符串生成

6.map()通过指定函数处理原始数组,并返回处理后的数组
  • map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。map() 方法按照原始数组元素顺序依次处理元素。
  • map() 不会对空数组进行检测。map() 不会改变原始数组。
  • array.map(function(currentValue,index,arr),thisValue)
7.pop()删除数组最后一个元素并返回处理后的数组
  • array.pop();
  • array.shift();删除数组的第一个元素
8.push()向数组的末尾添加一个或更多元素,并返回新的长度
  • Number =array.push(item1,item2,…,itemX);
  • array.unshift(item1,item2,…,itemX)) ; 向数组的开头添加一个或多个元素,并返回新的长度
9.reverse()颠倒数组中元素的顺序
  • 不影响原数组
  • Array=array.reverse();
10.slice()选取数组中的一部分,并返回一个新数组
  • 新数组中不包括end对应的值

  • Array=array.slice(start,end);

参数 描述
start 必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。
end 可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。
11.some()检测数组元素中是否有元素符合指定条件
  • some() 方法会依次执行数组的每个元素:如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。如果没有满足条件的元素,则返回false。
  • Boolean =array.some(function(currentValue,index,arr),thisValue);
12.sort()对数组的元素进行排序
  • 排序顺序可以是字符或数字,并按升序或降序。默认按字母升序。 这种方法会改变原始数组!

  • 注意:当数字是按字母顺序排列时”40”将排在”5”前面。使用数字排序,你必须通过一个函数作为参数来调用。函数指定数字是按照升序还是降序排列。

  • Array =array.sort(sortfunction);

    参数sortfunction可选,规定排定顺序,必须是函数

    返回值Array是对原数组的引用。注意,数组在原数组进行排序,不生成副本

13.splice()从数组中添加或删除,替换元素
  • 改变原数组

  • Array =array.splice(index,howmany,item1,item2,…,itemsX);

    参数index是必须的,规定从何处添加或删除元素,该参数是开始插入或删除的数组元素的下标,必须是数字

    howmany是必填项,规定应该删除多少元素,若未规定,则默认从index开始删除直到原数组结尾的所有元素

    item1,可选,要添加到数组的新元素

14.toString()把数组转为字符串并返回结果
  • 数组元素之间用逗号分隔
  • String=array.toString()
15.valueOf() 返回数组对象的原始值

Array=array.valueOf() 不会改变原数组

16.reduce()返回累计值
  • 定义:对数组中的每个元素执行一个自定义的累计器,将其结果汇总为单个返回值
  • 形式:array.reduce((t, v, i, a) => {}, initValue)
  • 参数
    • callback:回调函数(必选)
    • initValue:初始值(可选)
  • 回调函数的参数
    • total(t):累计器完成计算的返回值(必选)
    • value(v):当前元素(必选)
    • index(i):当前元素的索引(可选)
    • array(a):当前元素所属的数组对象(可选)
  • 过程
    • t作为累计结果的初始值,不设置t则以数组第一个元素为初始值
    • 开始遍历,使用累计器处理v,将v的映射结果累计到t上,结束此次循环,返回t
    • 进入下一次循环,重复上述操作,直至数组最后一个元素
    • 结束遍历,返回最终的t

reduce的精华所在是将累计器逐个作用于数组成员上,把上一次输出的值作为下一次输入的值

2.Boolean对象

  • Boolean 对象用于转换一个不是 Boolean 类型的值转换为 Boolean 类型值 (true 或者false).

3.Date对象

  • 四种创建方法
    • var d =new Date();
    • var d =new Date(milliseconds);
    • var d =new Date(dateString);
    • var d =new Date(year, month, day, hours, minutes, seconds, milliseconds);

4.Number对象

  • Number对象是原始数值的包装对象

    属性 描述
    constructor 返回对创建此对象的 Number 函数的引用。
    MAX_VALUE 可表示的最大的数。
    MIN_VALUE 可表示的最小的数。
    NEGATIVE_INFINITY 负无穷大,溢出时返回该值。
    NaN 非数字值。
    POSITIVE_INFINITY 正无穷大,溢出时返回该值。
    prototype 允许您有能力向对象添加属性和方法。
    方法 描述
    toExponential(x) 把对象的值转换为指数计数法。
    toFixed(x) 把数字转换为字符串,结果的小数点后有指定位数的数字。
    toPrecision(x) 把数字格式化为指定的长度。
    toString() 把数字转换为字符串,使用指定的基数。
    valueOf() 返回一个 Number 对象的基本数字值。

三 . 深入理解js

1.最小全局变量(Minimizing Globals)

  • js通过函数管理作用域。在函数内部声明的变量只在这个函数内部,函数外面不能使用。另一方面,全局变量就是在任何函数外面声明的或是未声明直接简单实用的

  • 每个js环境都有一个全局对象,但你在任意函数外面使用this就可以访问到。你创建的每一个全局变量都是这个全局对象的属性。在浏览器中,为方便起见,该全局对象有个附加属性叫做window,此window指向该全局对象本身

  • 全局变量的问题在于,你的JavaScript应用程序和web页面上的所有代码都共享了这些全局变量,他们住在同一个全局命名空间,所以当程序的两个不同部分定义同名但不同作用的全局变量的时候,命名冲突在所难免。

    • 第三方的JavaScript库
    • 广告方的脚本代码
    • 第三方用户跟踪和分析脚本代码
    • 不同类型的小组件,标志和按钮
  • 要想和其他脚本成为好邻居的话,尽可能少的使用全局变量是很重要的。一些减少全局变量的策略,例如命名空间模式或是函数立即自动执行,但是要想让全局变量少最重要的还是始终使用var来声明变量。

  • js因其特征,会不自觉地创建出全局变量。隐式创建全局变量的情况

    • 你可以不声明就可以使用变量,js会默认是全局对象的属性(js有隐含的全局概念)

    • 使用任务链进行var声明 在函数内部 var a=b=0;

      其中a是本地变量,而b是全局变量,因为这个是从右到左的赋值,首先通过赋值表达式b=0,此情况下b是未声明的。这个表达式的值是0,然后这个0就分配给通过var定义的全局变量a。若你提前声明了变量,使用链分配是比较好的,不会产生意料之外的情况

  • 另外一个避免全局变量的原因是可移植性,如果你想你的代码在不同环境(主机下)运行,使用全局变量如履薄冰,因为你会无意中覆盖你最初环境下不存在的主机对象(所以你原以为名称可以放心使用,实际上对于有些情况并不适用)

  • 忘记var的副作用(Side Effect when forgetting var)
    • 隐式全局变量和明确全局变量有小差异,即通过delete操作符让变量未定义的能力。
      • 通过var创建的全局变量(任何函数之外的程序中创建)是不能被删除的
      • 无var创建的隐式全局变量(无视是否在函数中创建)是能被删除的
    • 这表明,在技术上,隐式全局变量并不是真正的全局变量,但他们是全局对象的属性。属性是可以通过delete操作符删除的,而变量不能

// 定义三个全局变量
var global_var = 1;
global_novar = 2; // 反面教材
(function () {
global_fromfunc = 3; // 反面教材
}());
// 试图删除
delete global_var; // false
delete global_novar; // true
delete global_fromfunc; // true
// 测试该删除
typeof global_var; // “number”
typeof global_novar; // “undefined”
typeof global_fromfunc; // “undefined”

  • 访问全局对象(Access to the Global Object)

    在浏览器中,全局对象可以通过window属性在代码的任何位置访问(除非你做了些比较出格的事情,像是声明了一个名为window的局部变量)。但是在其他环境下,这个方便的属性可能被叫做其他什么东西(甚至在程序中不可用)。如果你需要在没有硬编码的window标识符下访问全局对象,你可以在任何层级的函数作用域中做如下操作:

var global=(function(){

return this;

}()); 这种方法可随时获得全局对象,因其在函数中被当作一个函数调用了(不是通过new构造),this总是指向全局对象。实际上这个病不适用于ECMAScript 5严格模式,所以,在严格模式下时,你必须采取不同的形式。例如,你正在开发一个JavaScript库,你可以将你的代码包裹在一个即时函数中,然后从 全局作用域中,传递一个引用指向this作为你即时函数的参数。

  • 单var形式(Single var Pattern)

    在函数顶部使用单var语句是比较有用的一种形式,其好处在于:

    • 提供了一个单一的地方去寻找功能所需要的所有局部变量
    • 防止变量在定义之前使用的逻辑错误
    • 帮助你记住声明的全局变量,因此较少了全局变量
    • 少代码(类型啊传值啊单线完成)
  • 预解析:var散布的问题(Hoisting: A Problem with Scattered vars)

    JavaScript中,你可以在函数的任何位置声明多个var语句,并且它们就好像是在函数顶部声明一样发挥作用,这种行为称为 hoisting(悬置/置顶解析/预解析)。当你使用了一个变量,然后不久在函数中又重新声明的话,就可能产生逻辑错误。对于JavaScript,只 要你的变量是在同一个作用域中(同一函数),它都被当做是声明的,即使是它在var声明前使用的时候。

    // 反例
    myname = “global”; // 全局变量
    function func() {
    alert(myname); // “undefined”
    var myname = “local”;
    alert(myname); // “local”
    }
    func();

2.代码处理的两个阶段

  • 第一阶段是变量,函数声明,以及正常格式的参数创建,这是一个解析和进入上下文的阶段
  • 第二阶段是代码执行,函数表达式和不合格的标识符(未声明的变量)被创建

四 . this 精讲

谁调用这个函数或方法,this关键字就指向谁

  • this总是返回属性或方法“当前”所在的对象
  • 如果一个函数在全局环境中运行,那么this就是指顶层对象(浏览器中为window对象)。

1.改变this指向的三大方法

1.call、apply、bind方法的共同点和区别:
  • apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;

  • apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文(函数的每次调用都会拥有一个特殊值——本次调用的上下文(context)——这就是this关键字的值。);

  • apply 、 call 、bind 三者都可以利用后续参数传参;

  • bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。

2.thisObj的取值有以下4种情况:

(1) 不传,或者传null,undefined, 函数中的this指向window对象

(2) 传递另一个函数的函数名,函数中的this指向这个函数的引用

(3) 传递字符串、数值或布尔类型等基础类型,函数中的this指向其对应的包装对象,如 String、Number、Boolean

(4) 传递一个对象,函数中的this指向这个对象

  • function.prototype.call(obj,arg1,arg2,…)
    • obj是this要指向的对象(一般会写成this),也就是想指定的上下文;arg1,arg2都是要传入的参数
    • 如果参数为空,null和undefined,则默认传入全局对象
  • function.prototype.apply(obj,[arg1,arg2,..])
    • apply()和call()差不多,但是apply的第二个参数是数组
  • function.prototype.bind(obj)
    • 将函数绑定到某个对象,然后返回一个新的函数
3.实例
1
2
3
4
5
6
7
8
9
10
11
function a(){     console.log(this);   //输出函数a中的this对象}       
function b(){}
var c={name:"call"}; //定义对象c
a.call(); //window
a.call(null); //window
a.call(undefined); //window
a.call(1); //Number
a.call(''); //String
a.call(true); //Boolean
a.call(b); //function b(){}
a.call(c); //Object

function class1(){

this.name=function(){

​ console.log(“我是class1内的方法”);

}

}

function class2(){

class1.call(this); //此行代码执行后,当前的this指向了class1(也可以说class2继承了class1)

}

var f=new class2();

f.name(); //调用的是class1内的方法,将class1的name方法交给class2使用

function eat(x,y){

console.log(x+y);

}

function drink(x,y){

console.log(x-y);

}

eat.call(drink,3,2);/输出:5。这个例子中的意思就是用 eat 来替换 drink,eat.call(drink,3,2) == eat(3,2) ,所以运行结果为:console.log(5);/

function Animal(){

this.name=”animal”;

this.showName=function(){

​ console.log(this.name);

}

}

function Dog(){

this.name=”dog”;

}

var animal=new Animal();

var dog=new Dog();

animal.showName.call(dog);//输出:dog

在上面的代码中,我们可以看到Dog里并没有showName方法,那为什么(this.name)的值是dog呢?

关键就在于最后一段代码(animal.showName.call(dog)),意思是把animal的方法放到dog上执行,也可以说,把animal 的showName()方法放到 dog上来执行,所以this.name 应该是 dog。

function Animal(name){

this.name=name;

this.showName=function(){

​ console.log(this.name);

}

}

function Dog(name){

Animal.call(this,name);

}

var dog=new Dog(“Crazy dog”);

dog.showName();//输出:Crazy dog

Animal.call(this) 的意思就是使用 Animal对象代替this对象,那么Dog就能直接调用Animal的所有属性和方法。著作权归作者所有。

  • 在JavaScript 中,某个函数的参数数量是不固定的,因此要说适用条件的话,当你的参数是明确知道数量时用 call ;而不确定的时候用 apply,然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments 这个数组来遍历所有的参数。著作权归作者所有。

详情请看:http://ghmagical.com/article/page/id/UPLfoGI9vJ91

五 . 垃圾回收机制

  • js具有自动垃圾回收机制(GC:Garbage Collection),也就是说执行环境会负责管理代码执行过程中使用的内存
  • 原理:垃圾收集器会定期(周期性)找出那些不再继续使用的变量,然后释放其内存。此过程并非实时的,因其开销会很大。
  • 不再使用的变量也就是生命周期结束的变量,当让只可能是局部变量,全局变量的生命周期直至浏览器卸载页面才会结束,局部变量只在函数执行过程中存在,而在这个过程会为局部变量在堆和栈分配相应的空间,以存储它们的值,然后在函数中使用这些变量,直至函数结束,而闭包由于内部函数的原因,外部函数并不能算是结束。

六. 枚举

ECMAScript原始值和引用值

1.原始值

存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。

2.引用值

存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。

为变量赋值时,ECMAScript 的解释程序必须判断该值是原始类型,还是引用类型。要实现这一点,解释程序则需尝试判断该值是否为 ECMAScript 的原始类型之一,即 Undefined、Null、Boolean、Number和String型。由于这些原始类型占据的空间是固定的,所以可将他们存储在较小的内存区域 - 栈中。这样存储便于迅速查寻变量的值。

在许多语言中,字符串都被看作引用类型,而非原始类型,因为字符串的长度是可变的。ECMAScript打破了这一传统。

如果一个值是引用类型的,那么它的存储空间将从堆中分配。由于引用值的大小会改变,所以不能把它放在栈中,否则会降低变量查寻的速度。相反,放在变量的栈空间中的值是该对象存储在堆中的地址。地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响

存储在堆和栈中的原始值和引用值

3.对象

1.属性
  • constructor:对创建对象的函数的引用(指针)。对于Object对象,该指针指向原始的Object()函数
  • prototype:对该对象的原型的引用。对于所有的对象,他默认返回Object对象的一个实例
2.方法
  • hasOwnProperty(property):判断对象是否有某个特定的属性。必须用字符串指定该属性(o.hasOwnProperty(“name”))
  • IsPrototypeOf(object):判断该对象是否为另一个对象的原型
  • PropertyIsEnumerable:判断给定的属性是否可以用for…in语句进行枚举
  • ToString():返回对象的原始字符串表示。对于Object对象,ECMA-262没有定义这个值,所以不同的ECMAScript实现具有不同的值
  • ValueOf()返回最适合该对象的原始值。对于许多对象,该方法返回的值都与ToString()的返回值相同
  • 上面列出的每种属性和方法都会被其他对象覆盖

4.String对象

  • localeCompare()方法,对字符串进行排序。该方法有一个参数-要进行比较的字符串,返回的是下列三个值之一

    • 如果String对象按照字母顺序排在参数中的字符串之前,返回负数
    • 等于参数中的字符串,返回0
    • 排在参数中的字符串之后,返回正数
  • localeCompare()方法的独特之处在于,实现所处的区域(locale,兼指国家/地区和语言)确切说明了这种方法运行的方式。在美国,英语是ECMAScript实现的标准语言,localeCompare()是区分大小写的,大写字母在字母顺序上排在小写字母之后。不过,在其他区域,情况可能并非如此。

  • slice()和substring()

    • ECMAScript提供了两种方法从字串创建字符串值,即slice()和substring()。这两种返回的都是要处理的字符串的子串,都接受一个或两个参数,第一个参数是要获取字串的起始位置,第二个参数(如果使用的话)是要获取子串终止前的位置(也就是说,获取终止位置不包括在返回值内)。若省略第二个参数,终值位就默认为字符串的长度。但是两种方法都不影响String对象本身的值

    • 对于负数参数,slice()方法会用字符串的长度加上参数,substring()方法则将其作为0处理(也就是忽略他)

      var oStringObject = new String(“hello world”);
      alert(oStringObject.slice(“-3”)); //输出 “rld”
      alert(oStringObject.substring(“-3”)); //输出 “hello world”
      alert(oStringObject.slice(“3, -4”)); //输出 “lo w”
      alert(oStringObject.substring(“3, -4”)); //输出 “hel”

      substring()方法则将两个参数解释为substring(3, 0),实际上即substring(0, 3),因为substring()总把较小的数字作为起始位,较大的数字作为终止位。因此,substring(“3, -4”)返回的是”hel”。

  • toLowerCase()和toUpperCase()方法是原始的,是以java.lang.String中相同方法为原型实现的。

    toLocaleLowerCase()和toLocaleUpperCase()方法是基于特定的区域实现的

    • 一般来说,如果不知道在以哪种编码运行一种语言,则使用区域特定的方法比较安全。
    • String对象的所有属性和方法都可应用于String原始值上,因为它们是伪对象。
  • instanceof运算符

    • 解决使用typeof运算符时,所有类型的对象都返回“object”

5.整数

  • ECMAScript中,所有整数字面量默认都是有符号32位整数,前31位(每一位都表示2的幂)是整数数值,最后一位表示符号,0表示正数,1表示负数

  • 负整数:负数也存储为二进制代码,不过采用的形式是二进制补码。计算补码三部曲:

    • 确定该数字的非负版本的二进制表示(如,要计算-18的二进制补码,首先要确定18的二进制表示)
    • 求得二进制反码,即把0替换成1,把1替换成0
    • 在二进制反码上加上1
  • 位运算NOT(~)三部曲

    • 把运算数转化成32位数字

    • 把二进制转换成他的二进制反码

    • 把二进制数转化成浮点数

      位运算NOT实质上是对数字求负,然后减1,因此25变成-26

    • 如果运算数是对象,返回false

    • 如果运算数是数字0,返回true

    • 如果运算数是0以外的任何数字,返回false

    • 如果运算数是null,返回true

    • 如果运算数是NaN,返回true

    • 如果运算数是undefined,发生错误。

  • AND运算符的运算数可以是任何类型的

    • obj && boolean ——–obj
    • obj1 && obj2 ———obj2
    • 有null ———–null
    • 有NaN ——返回NaN
    • 第一个是undefined或第一个是true,第二个是undefined——发生错误
    • 第一个是false,第二个是undefined——返回false,因为第二个没被计算
  • 乘法运算符*

    • 如果某个运算数是NaN,结果就是NaN
    • Infinity乘以0,结果是NaN
    • Infinity乘以0以外的数,结果为Infinity或-Infinity
  • 除法运算符/

    • 如果结果太大或太小,生成的结果是Infinity或-infinity
    • 如果某个运算数是NaN,结果是NaN
    • Infinity被Infinity除,结果是NaN。Infinity/Infinity=NaN
    • Infinity被任何数字除,结果是Infinity 某个数/Infinity=Infinity
    • 0除以一个非无穷大的数字,结果为NaN 0/某个数=NaN
  • 取余%

    • Infinity%某数=NaN 某数%0=NaN
    • Infinity%Infinity=NaN
    • 被除数%Infinity=被除数
    • 0%某数=0
  • 加法+

    • 某个运算数是NaN,结果为NaN
    • (-Infinity)+(-Infinity)= -Infinity
    • Infinity + (-Infinity)=NaN
    • (+0)+(+0)=(+0)
    • (-0)+(+0)=(+0)
    • (-0)-(-0)=(-0)
    • (-0)+(-0)=(-0)
    • 如果两个运算数都是字符串,把第二个字符串连接到第一个上。
    • 如果只有一个运算数是字符串,把另一个运算数转换成字符串,结果是两个字符串连接成的字符串。
  • 等性运算符==和!=

    • 如果一个运算数是Boolean值,在检查相等性之前,把它转换成数字值,true为1,false为0

    • 字符串和数字,将字符串转成数字

    • 对象和字符串,将对象转为字符串

    • 对象和数字,将对象转成数字

    • 值null和undefined相等

    • 在检查相等性时,不能把null和undefined转换成其他值

    • 有NaN,等号返回false,非等号返回true

    • 如果两个运算数是对象,那比较的是他们的引用值,若指向同一对象,则等号返回true,否则两个运算数不等

      表达式
      null == undefined true
      “NaN” == NaN false
      5 == NaN false
      NaN == NaN false
      NaN != NaN true
      false == 0 true
      true == 1 true
      true == 2 false
      undefined == 0 false
      null == 0 false
      “5” == 5 true

6.语句

1.有标签的语句
  • break 语句和 continue 语句都可以与有标签的语句联合使用,返回代码中的特定位置。当循环内部还有循环时,会这样做
  • with语句用于设置代码在特定对象中的作用域

var sMessage = “hello”;
with(sMessage) {
alert(toUpperCase()); //输出 “HELLO”
}

(1)在这个例子中,with语句用于字符串,所以调用toUpperCase()方法时,解释程序将检查该方法是否是本地程序。如果不是,他将检查伪对象sMessage,看他是否为该对象的方法,然后,alert输出“HELLO”,因为解释程序找到了字符串”hello“的toUpperCase()方法

(2)with语句是运行缓慢的代码块,尤其是在已设置了属性值时。大多情况下,如果可能,最好避免使用它

七. 面向对象

1.具备的四种能力

  • 封装:把相关信息(数据或方法)存储在对象中的能力
  • 聚集:把一个对象存储在另一个对象内的能力
  • 继承:有另一个类(或多个类)得来类的属性和方法的能力
  • 多态:编写能以多种方法运行的函数或方法的能力

2.对象的应用

  • 对象的创建和销毁都在js执行过程中发生

3.对象废除

  • ECNAScript拥有无用存储单元搜集程序(garbage collection routine),意味着不必专门销毁对象来释放内存。当没有对象引用时,称该对象被废除了(derefence)。运行无用存储单元收集程序时,所有废除的对象都被销毁。每当执行完它的代码,无用存储单元收集程序都会运行,释放所有的局部变量,还有在一些不可预知的情况下,无用存储单元收集程序也会运行
  • 把对象的所有引用都设置为null,可以强制性的废除材料

4.绑定

  • 即把对象的接口与对象实例结合起来的方法
  • 早绑定(early binding)是指在实例化对象之前定义它的属性和方法,这样编译器或解释程序就能够提前转换机器代码。在 Java 和 Visual Basic 这样的语言中,有了早绑定,就可以在开发环境中使用 IntelliSense(即给开发者提供对象中属性和方法列表的功能)。ECMAScript 不是强类型语言,所以不支持早绑定。
  • 另一方面,晚绑定(late binding)指的是编译器或解释程序在运行前,不知道对象的类型。使用晚绑定,无需检查对象的类型,只需检查对象是否支持属性和方法即可。ECMAScript 中的所有变量都采用晚绑定方法。这样就允许执行大量的对象操作,而无任何惩罚。

5.作用域

  • 指的是变量的适用范围
  • ECMAScript只有公共作用域,所有对象的作用域都是公共的。由于缺少私有作用域,开发者确定了一个规约,说明哪些属性和方法应该被看做私有的。这种规约规定在属性前后加下划线
  • ECMAScript没有静态作用域(静态作用域定义的属性和方法任何时候都能从同一位置访问),但可以为构造函数提供属性和方法,构造函数是函数,函数是对象,对象可以有属性和方法

6.使用动态原型方法类的属性和方法

  • 在构造函数内定义非函数属性,而函数属性则利用原型属性定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Car(sColor,iDoors,iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike","John");

if (typeof Car._initialized == "undefined") {
Car.prototype.showColor = function() {
alert(this.color);
};

Car._initialized = true;
}
}
  • 知道检查typeof Car.__initialized是否等于“undefined”之前,这个构造函数都为改变。这行代码是动态原型方法中最重要的一部分。如果这个值没定义,构造函数将用原型方法继续定义对象的方法,然后把Car._initialized设置为true,如果这个值定义了,(它的值为true,typeof的值为Boolean),那么就不再创建该方法。简而言之,该方法使用(_initialized)来判断是否已给原型赋予了任何方法,该方法只创建并赋值一次。

7.ECMAScript的字符串

  • ECMAScript的字符串是不可变的,即它们的值是不可变的

var str=”hello”;str += “world”;

创建此段代码的实际步骤(特别耗资源)

  • 创建存储“hello”字符串
  • 创建存储“world”的字符串
  • 创建连接结果的字符串
  • 把str的当前结果复制到结果中
  • 把“world”复制到结果中
  • 更新str,使它指向结果

解决方法是用Array对象存储字符串,然后用join()方法(参数是空字符串)创建最后的字符串(但是不能确切反映出他的意图)

var arr = new Array();
arr[0] = “hello “;
arr[1] = “world”;
var str = arr.join(“”);

实现步骤

  • 创建存储结果的字符串
  • 把每个字符串复制到结果中的合适位置

最好的方法是使用StringBuffer类包装该功能

function StringBuffer(){

this._strings=new Array();

}

StringBuffer.prototype.append=function(str){

this._strings.push(str);

};

StringBuffer.prototype.toString=function(){

return this._strings.join(“”);

};

这段代码首先要注意的是strings属性,本意是私有属性。它只有两个方法,append()和toString()方法。append()方法只有一个参数,他把该参数附加到字符串数组中,toString()方法调用数组的join方法,返回真正连接成的字符串。

var buffer = new StringBuffer ();
buffer.append(“hello “);
buffer.append(“world”);
var result = buffer.toString();

八 . 继承机制实现

  • 要用ECMAScript实现继承机制,您可以从要继承的基类入手。所有开发者定义的类都可以作为基类。出于安全原因,本地类和宿主类不能作为基类,这样可以防止公用访问编译过的浏览器级的代码,因为这些代码可被用于恶意攻击

  • 选定基类后,就可以创建它的子类了。是否使用基类完全由你决定。有时,你可能创建一个不能直接使用的基类,他只是用于给函数提供通用函数。这种情况下,基类被看成是抽象类。

  • 创建的子类将继承超类的所有属性和方法,包括构造函数及方法的实现。记住,所有的属性和方法都是公用的,因此子类可以直接访问这些方法。子类还可以添加超类中没有的属性和方法,也可以覆盖超类中的属性和方法

  • JavaScript实现继承并非明确规定,而是通过模仿实现的,故和其他功能一样,不止一种实现方式。这意味着所有的继承细节并非完全由解释程序处理。作为开发者,你有权决定最适合的继承方法

1.对象冒充

原理:构造函数使用this关键字给所有属性和方法赋值(即采用类声明的构造函数方式)。因为构造函数只是一个函数,所以可以使ClassA构造函数成为ClassB的方法,然后调用它。ClassB就会收到ClassA的构造函数中定义的属性和方法。

function ClassA(scolor){

this.color=scolor;

this.sayColor=function(){

alert(this.color);}

}

function ClassB(scolor){

this.newMethod=ClassA; this.newMethod(scolor); delete this.newMethod;

this.name = sName;
this.sayName = function () {
alert(this.name);
};

}

在这段段代码中,为ClassA赋予方法newMethod(请记住,函数名只是指向它的指针)。然后调用该方法,传递给它的是ClassB构造函数,第三行行删除对ClassA的引用,这样以后就不能再调用它了。所有新属性或新方法都必须在删除了新方法的代码行后才能执行。否则,可能会覆盖超类的相关方法和属性。

  • 对象冒充可以实现多重继承,即一个类可继承多个超类

继承机制 UML 图示实例

function ClassZ() {
this.newMethod = ClassX;
this.newMethod();
delete this.newMethod;
this.newMethod = ClassY;
this.newMethod();
delete this.newMethod;
}

这里存在一个弊端,如果存在两个类 ClassX 和 ClassY 具有同名的属性或方法,ClassY 具有高优先级。因为它从后面的类继承。除这点小问题之外,用对象冒充实现多重继承机制轻而易举。

2.使用call(对象参数,形参1,2,..)

3.使用apply(对象参数,形参数组)

九.object对象

  • JavaScript 原生提供Object对象(注意起首的O是大写),所有其他对象都继承自这个对象。Object本身也是一个构造函数,可以直接通过它来生成新对象。

    var obj = new Object();

  • Object作为构造函数使用时,可接受一个参数。如果该参数是一个对象,则直接返回这个对象;如果是原始类型的值,则返回该值的包装对象。注意,通过new Object()的写法生成新对象,与字面量的写法o = {}是等价的。

    var o1 = {a: 1};
    var o2 = new Object(o1);
    o1 === o2 // true
    new Object(123) instanceof Number
    // true

Object对象上面部署一个方法的两种做法。

1.部署在Object对象本身

比如,在Object对象上面定义一个print方法,显示其他对象的内容。

Object.print = function (o) { console.log(o) } ;

var o =new Object() ;

Object.print(o);

2.部署在Object.prototype对象
  • 所有构造函数都有一个prototype属性,指向一个原型对象。凡是在Object.prototype对象上面定义的属性都将被所有实例对象所共享

    Object.prototype.print = function () { console.log(this) };

    var o = new Object();

    o.print();

    上面代码在Object.prototype定义了一个print方法,然后生成一个Object的实例o。o直接继承了Object.prototype的属性和方法,可以在自身调用它们,也就是说,o对象的print方法实质上是调用Object.prototype.print方法。。

Object()方法

  • 可将任意值转为对象。这个方法常用于保证某个值一定是对象。如果参数是原始类型的值,Object方法返回对应的包装对象的实例

    Object() instanceof Object // true
    Object(undefined) // 返回一个空对象
    Object(undefined) instanceof Object // true
    Object(null) // 返回一个空对象
    Object(null) instanceof Object // true
    Object(1) // 等同于 new Number(1)
    Object(1) instanceof Object // true
    Object(1) instanceof Number // true
    Object(‘foo’) // 等同于 new String(‘foo’)
    Object(‘foo’) instanceof Object // true
    Object(‘foo’) instanceof String // true
    Object(true) // 等同于 new Boolean(true)
    Object(true) instanceof Object // true
    Object(true) instanceof Boolean // true

  • 如果参数是一个对象,他总是返回原对象

    var arr = [];
    Object(arr) // 返回原数组
    Object(arr) === arr // true
    var obj = {};
    Object(obj) // 返回原对象
    Object(obj) === obj // true
    var fn = function () {};
    Object(fn) // 返回原函数
    Object(fn) === fn // true

    利用这一点,可以写一个判断变量是否为对象的函数。

    function isObject(value) {
    return value === Object(value);
    }
    isObject([]) // true
    isObject(true) // false

Object对象的静态方法

  • 是指部署在Object对象自身的方法

  • Object.keys方法和Object.getOwnPropertyNames方法很相似,一般用来遍历对象的属性。它们的参数都是一个对象,都返回一个数组,该数组的成员都是对象自身的(而不是继承的)所有属性名。它们的区别在于,Object.keys方法只返回可枚举的属性Object.getOwnPropertyNames`方法还返回不可枚举的属性名。

    var o = {
    p1: 123,
    p2: 456
    };
    Object.keys(o)
    // [“p1”, “p2”]
    Object.getOwnPropertyNames(o)
    // [“p1”, “p2”]

    有不可枚举属性length

    var a = [“Hello”, “World”];
    Object.keys(a)
    // [“0”, “1”]
    Object.getOwnPropertyNames(a)
    // [“0”, “1”, “length”]

  • 由于JavaScript没有提供计算对象属性个数的方法,所以可以用这两个方法代替。

    Object.keys(o).length

    Object.getOwnPropertyNames(o).length

    一般情况下,几乎总是使用Object.keys方法遍历数组的属性

对象属性模型的相关方法

  • Object.getOwnPropertyDescriptor():获取某个属性的attributes对象。
  • Object.defineProperty():通过attributes对象,定义某个属性。
  • Object.defineProperties():通过attributes对象,定义多个属性。
  • Object.getOwnPropertyNames():返回直接定义在某个对象上面的全部属性的名称。

控制对象状态的方法

  • Object.preventExtensions():防止对象扩展。
  • Object.isExtensible():判断对象是否可扩展。
  • Object.seal():禁止对象配置。
  • Object.isSealed():判断一个对象是否可配置。
  • Object.freeze():冻结一个对象。
  • Object.isFrozen():判断一个对象是否被冻结。

原型链相关方法

  • Object.create():该方法可以指定原型对象和属性,返回一个新的对象。
  • Object.getPrototypeOf():获取对象的Prototype对象。

Object对象都有的六大实例方法

  • valueOf():返回当前对象对应的值

    • valueOf方法的作用是返回一个对象的“值”,默认情况下返回对象本身。

      var o = new Object();
      o.valueOf() === o // true

    • valueOf`方法的主要用途是,JavaScript自动类型转换时会默认调用这个方法

      var o = new Object();
      o.valueOf = function (){
      return 2;
      };
      1 + o // 3

  • toString():返回当前对象对应的字符串形式

    • toString方法的作用是返回一个对象的字符串形式,默认情况下返回类型字符串。

      var o1 = new Object();
      o1.toString() // “[object Object]”
      var o2 = {a:1};
      o2.toString() // “[object Object]”

    • 自动类型转换时

      var o = new Object();
      o.toString = function () {
      return ‘hello’;
      };
      o + ‘ ‘ + ‘world’ // “hello world”

[1, 2, 3].toString() // "1,2,3"
'123'.toString() // "123"
(function () {
return 123;
}).toString()
// "function () {
//   return 123;
// }"
(new Date()).toString()
// "Tue May 10 2016 09:11:31 GMT+0800 (CST)"
  • 实例对象可能会自定义toString方法,覆盖掉Object.prototype.toString方法。通过函数的call方法,可以在任意值上调用Object.prototype.toString方法,帮助我们判断这个值的类型。

    Object.prototype.toString.call(value)

    不同数据类型的Object.prototype.toString方法返回值如下。

    • 数值:返回[object Number]
    • 字符串:返回[object String]
    • 布尔值:返回[object Boolean]
    • undefined:返回[object Undefined]
    • null:返回[object Null]
    • 数组:返回[object Array]
    • arguments对象:返回[object Arguments]
    • 函数:返回[object Function]
    • Error对象:返回[object Error]
    • Date对象:返回[object Date]
    • RegExp对象:返回[object RegExp]
    • 其他对象:返回[object Object]
  • 也就是说,Object.prototype.toString可以得到一个实例对象的构造函数。

    1
    2
    3
    4
    5
    6
    7
    8
    Object.prototype.toString.call(2) // "[object Number]"
    Object.prototype.toString.call('') // "[object String]"
    Object.prototype.toString.call(true) // "[object Boolean]"
    Object.prototype.toString.call(undefined) // "[object Undefined]"
    Object.prototype.toString.call(null) // "[object Null]"
    Object.prototype.toString.call(Math) // "[object Math]"
    Object.prototype.toString.call({}) // "[object Object]"
    Object.prototype.toString.call([]) // "[object Array]"

    利用这个特性,可以写出一个比typeof运算符更准确的类型判断函数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var type = function (o){
    var s = Object.prototype.toString.call(o);
    return s.match(/\[object (.*?)\]/)[1].toLowerCase();
    };

    type({}); // "object"
    type([]); // "array"
    type(5); // "number"
    type(null); // "null"
    type(); // "undefined"
    type(/abcd/); // "regex"
    type(new Date()); // "date"

    在上面这个type函数的基础上,还可以加上专门判断某种类型数据的方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    ['Null',
    'Undefined',
    'Object',
    'Array',
    'String',
    'Number',
    'Boolean',
    'Function',
    'RegExp',
    'NaN',
    'Infinite'
    ].forEach(function (t) {
    type['is' + t] = function (o) {
    return type(o) === t.toLowerCase();
    };
    });

    type.isObject({}) // true
    type.isNumber(NaN) // true
    type.isRegExp(/abc/) // true
  • toLocaleString():返回当前对象对应的本地字符串形式。

  • hasOwnProperty():判断某个属性是否为当前对象自身的属性值还是继承自原型对象的属性

  • isPrototypeOf():判断当前对象是否为另一个对象的原型

  • propertyIsEnumerable():判断某个属性是否可枚举

Array对象

  • Array是JavaScript的内置对象,同时也是一个构造函数,可以用它生成新的数组。

    1
    2
    3
    var arr = new Array(2);
    arr.length // 2
    arr // [ undefined x 2 ]
  • Array构造函数有一个很大的问题,就是不同的参数,会导致它的行为不一致。`因此,不建议使用它生成新数组,直接使用数组字面量是更好的做法。

    // 无参数时,返回一个空数组
    new Array() // []
    // 单个正整数参数,表示返回的新数组的长度
    new Array(1) // [ undefined ]
    new Array(2) // [ undefined x 2 ]
    // 非正整数的数值作为参数,会报错
    new Array(3.2) // RangeError: Invalid array length
    new Array(-3) // RangeError: Invalid array length
    // 单个非正整数参数(比如字符串、布尔值、对象等),
    // 则该参数是返回的新数组的成员
    new Array(‘abc’) // [‘abc’]
    new Array([1]) // [Array[1]]
    // 多参数时,所有参数都是返回的新数组的成员
    new Array(1, 2) // [1, 2]
    new Array(‘a’, ‘b’, ‘c’) // [‘a’, ‘b’, ‘c’]

  • 注意,如果参数是一个正整数,返回数组的成员都是空位。虽然读取的时候返回undefined,但实际上该位置没有任何值。虽然可以取到length属性,但是取不到键名。

    var arr = new Array(3);
    arr.length // 3
    arr[0] // undefined
    arr[1] // undefined
    arr[2] // undefined
    0 in arr // false
    1 in arr // false
    2 in arr // false

  • Array.isArray():判断一个值是否为数组,弥补typeof运算符的不足

1.Array实例的方法
  • valueOf()方法返回数组本身

    var a = [1, 2, 3];
    a.valueOf() // [1, 2, 3]

  • toString()方法返回数组的字符串形式

    var a = [1, 2, 3];
    a.toString() // “1,2,3”
    var a = [1, 2, 3, [4, 5, 6]];
    a.toString() // “1,2,3,4,5,6”

  • push()方法用于在数组的末端添加一个或多个元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。

    var a = [];
    a.push(1) // 1
    a.push(‘a’) // 2
    a.push(true, {}) // 4
    a // [1, ‘a’, true, {}]

  • 合并两个数组

    var a = [1, 2, 3];
    var b = [4, 5, 6];
    Array.prototype.push.apply(a, b)
    // 或者
    a.push.apply(a, b)
    // 上面两种写法等同于
    a.push(4, 5, 6)
    a // [1, 2, 3, 4, 5, 6]

  • push方法还可用于向对象添加元素,添加后的对象变成类似数组的对象,即新加入元素的键对应数组的索引,并且对象有一个length属性,其中的length属性是指加入键名的个数

    var a= {a:1};

    [].push.call(a,2);

    a //{a:1 ,0:2 , length :1}

    [].push.call(a,[3]);

    a // {a:1,0:2,1:[3],length:2};

  • pop()方法用于删除数组的最后一个元素,并返回该元素。该方法会改变原数组

    var arr=[‘a’,’b’,’c’];

    a.pop() //‘c’

    a //[‘a’,’b’]

  • 对空数组使用pop方法,不是犯错,而是返回undefined

    [ ].pop() //undefined

  • push和pop结合使用就构成后进先出的栈结构

  • join()方法以参数作为分隔符,将所有数组组成一个字符串返回。如果不提供参数,默认用逗号分隔

    var str=”abcdefgh”;

    var arr=str.split(‘’); //[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”]

    arr.join(‘’); //“abcdefgh”

    arr.join(‘ ‘); //a b c d e f g h’;

  • 如果数组成员是undefined或null或空位,会被转成空字符串

    [undefined,null].join(‘#’) //‘#’

    [‘a’, ,’b’].join(‘-‘) //‘a- -b’

  • 这个方法也可以用于字符串,通过call方法

    Array.prototype.join.call(‘hello’,’-‘) //“h-e-l-l-o”

  • join方法也可以用于类似数组的对象

    var obj={0:’a’,1:’b’,length:2};

    Array.prototype.join.call(obj,’-‘) //‘a-b’

  • concat()用于将多个数组合并。它将新数组的成员添加到原数组的尾部,然后返回一个新数组,原数组不变

    [‘hello’].concat([‘world’], [‘!’])
    // [“hello”, “world”, “!”]

  • concat方法如果不提供参数,concat方法返回当前数组的一个浅拷贝。所谓“浅拷贝”,指的是如果数组成员包括复合类型的值(比如对象),则新数组拷贝的是该值的引用(你改我也会改)。

    var obj = { a:1 };
    var oldArray = [obj];
    var newArray = oldArray.concat();
    obj.a = 2;
    newArray[0].a // 2

  • concat方法也可以用于将对象合并为数组,但是必须借助call方法

    [].concat.call({a: 1}, {b: 2})
    // [{ a: 1 }, { b: 2 }]
    [].concat.call({a: 1}, [2])
    // [{a: 1}, 2]
    [2].concat({a: 1})
    // [2, {a: 1}]

  • shift用于删除数组的第一个元素,并返回该元素。注意,该方法会改变原数组

    var a=[‘a’,’b’,’c’];

    a.shift();

    a //[‘b’,’c’]

  • shift方法可以遍历并清空一个数组。

    1
    2
    3
    4
    5
    6
    7
    8
    var list = [1, 2, 3, 4, 5, 6];
    var item;

    while (item = list.shift()) {
    console.log(item);
    }

    list // []

    pushshift结合使用,就构成了“先进先出”的队列结构(queue)。

  • unshift方法用于在数组的第一个位置添加元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。

    1
    2
    3
    4
    var a = ['a', 'b', 'c'];

    a.unshift('x'); // 4
    a // ['x', 'a', 'b', 'c']

    unshift方法可以在数组头部添加多个元素。

    1
    2
    3
    var arr = [ 'c', 'd' ];
    arr.unshift('a', 'b') // 4
    arr // [ 'a', 'b', 'c', 'd' ]
  • reverse()方法用于颠倒数组中的元素的顺序,返回改变后的数组。注意,会改变原数组

    var a = [‘a’, ‘b’, ‘c’];
    a.reverse() // [“c”, “b”, “a”]
    a // [“c”, “b”, “a”]

  • slice方法用于提取原数组的一部分,返回一个新数组,原数组不变。它的第一个参数为起始位置(从零开始),第二个参数为1终止位置(但不包括该元素本身)。若省略第二个参数,则一直返回到原数组最后一个成员,相当于原数组的拷贝。

    a.slice(0) // [“a”, “b”, “c”]
    a.slice(1) // [“b”, “c”]
    a.slice(1, 2) // [“b”]
    a.slice(2, 6) // [“c”]
    a.slice() // [“a”, “b”, “c”]

  • slice方法的参数是负数时表示倒数计算的位置。

    var a = [‘a’, ‘b’, ‘c’];
    a.slice(-2) // [“b”, “c”]
    a.slice(-2, -1) // [“b”]

  • 如果参数值大于数组成员的个数,或者第二个参数小于第一个参数,则返回空数组。

    var a = [‘a’, ‘b’, ‘c’];
    a.slice(4) // []
    a.slice(2, 1) // []

  • slice方法的一个重要应用,是将类似数组的对象转为真正的数组。

    Array.prototype.slice.call({ 0: ‘a’, 1: ‘b’, length: 2 })
    // [‘a’, ‘b’]
    Array.prototype.slice.call(document.querySelectorAll(“div”));
    Array.prototype.slice.call(arguments);

  • splice方法用于删除原数组的一部分成员,并可以在被删除的位置添加入新的数组成员,返回值是被删除的元素。注意,该方法会改变原数组。

    splice的第一个参数是删除的起始位置,第二个参数是被删除的元素个数。如果后面还有更多的参数,则表示这些就是要被插入数组的新元素。

    // 格式
    arr.splice(index, count_to_remove, addElement1, addElement2, …);
    // 用法
    var a = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’];
    a.splice(4, 2) // [“e”, “f”]
    a // [“a”, “b”, “c”, “d”]

  • 如果只提供第一个参数,等同于将原数组在指定位置拆分成两个数组。

    var a = [1, 2, 3, 4];
    a.splice(2) // [3, 4]
    a // [1, 2]

  • sort方法对数组成员进行排序,默认是按照字典顺序排序。排序后,原数组将被改变。

  • 如果想让sort方法按照自定义方式排序,可以传入一个函数作为参数,表示按照自定义方法进行排序。该函数本身又接受两个参数,表示进行比较的两个元素。如果返回值大于0,表示第一个元素排在第二个元素后面;其他情况下,都是第一个元素排在第二个元素前面。

    [10111, 1101, 111].sort(function (a, b) {
    return a - b;
    })
    // [111, 1101, 10111]
    [
    { name: “张三”, age: 30 },
    { name: “李四”, age: 24 },
    { name: “王五”, age: 28 }
    ].sort(function (o1, o2) {
    return o1.age - o2.age;
    })
    // [
    // { name: “李四”, age: 24 },
    // { name: “王五”, age: 28 },
    // { name: “张三”, age: 30 }
    // ]

  • map方法对数组的所有成员依次调用一个函数,根据函数结果返回一个新数组。map方法接受一个函数作为参数。该函数调用时,map方法会将其传入三个参数,分别是当前成员、当前位置和数组本身。

    var numbers = [1, 2, 3];
    numbers.map(function (n) {
    return n + 1;
    });
    // [2, 3, 4]

    numbers
    // [1, 2, 3]

    [1, 2, 3].map(function(elem, index, arr) {
    return elem * index;
    });
    // [0, 2, 6]

    map方法不仅可以用于数组,还可以用于字符串,用来遍历字符串的每个字符。但是,不能直接使用,而要通过函数的call方法间接使用,或者先将字符串转为数组,然后使用。

    1
    2
    3
    4
    5
    6
    7
    8
      var upper = function (x) {
    return x.toUpperCase();
    };
    [].map.call('abc', upper)
    // [ 'A', 'B', 'C' ]
    // 或者
    'abc'.split('').map(upper)
    // [ 'A', 'B', 'C' ]

js基础

在线工具库:https://123.w3cschool.cn/webtools

一 . js简介

1.概念

  • javascript是世界上最流行的脚本语言。js是属于web的语言,他适合与PC,笔记本电脑,平板电脑和移动电话。ja被设计成向HTNL页面增加交互性。
    • 脚本语言:指的是他不具备开发操作系统的能力,而是只用来编写控制其他大型应用程序(比如浏览器)的“脚本”
  • 通过嵌入HTML来实现各种酷炫的动态效果,为用户提供赏心悦目的浏览效果。所有现代的 HTML 页面都使用 JavaScript,可以用于改进设计、验证表单、检测浏览器、创建cookies等。
  • javaScript 是一种轻量级的编程语言。JavaScript 是可插入 HTML 页面的编程代码。JavaScript 插入 HTML 页面后,可由所有的现代浏览器执行。
  • javascript也是一种嵌入式(embedded)语言。它本身提供的核心语法不算很多,只是用来做一些数学和逻辑运算。js本身不提供任何与I/O(输入/输出)相关的API,主要靠宿主环境(host)提供,所以js只适合嵌入更大型的应用程序环境,去调用宿主环境提供的底层API。目前,已经嵌入JavaScript的宿主环境有多种,最常见的环境就是浏览器,另外还有服务器环境,也就是Node项目
  • 从语法角度看,javascript语言是一种“对象模型”语言。各种宿主环境通过这个模型,描述自己的功能和操作接口,从而通过js控制这些功能。但是,js并不是纯粹的“面型对象语言”,还支持其他编程范式(比如函数式编程)

2.支持编译运行。

  • JavaScript 语言本身,虽然是一种解释型语言,但是在现代浏览器中,JavaScript 都是编译后运行。程序会被高度优化,运行效率接近二进制程序。而且,JavaScript 引擎正在快速发展,性能将越来越好。
  • 此外,还有一种 WebAssembly 格式,它是 JavaScript 引擎的中间码格式,全部都是二进制代码。由于跳过了编译步骤,可以达到接近原生二进制代码的运行速度。各种语言(主要是 C 和 C++)通过编译成 WebAssembly,就可以在浏览器里面运行。

3.事件驱动和非阻塞式设计

  • JavaScript 程序可以采用事件驱动(event-driven)和非阻塞式(non-blocking)设计,在服务器端适合高并发环境,普通的硬件就可以承受很大的访问量。

4.javascript与java的关系

Java javascript
强类型 弱类型(同一变量可以存放不同类型的变量(但是始终存放同一类型是良好的编码习惯)

必须在JAVA虚拟机上运行,且事先需要进行编译 不依托编辑器,在浏览器就可以实现,边解释边执行

二 . 输出

1.直接写入HTML输出流

document.write(“输出内容”); 将内容写入HTML文档

  • 你只能在HTNL输出中使用document.write。如果在文档加载完成后使用该方法,会覆盖整个文档。

2.弹出警告框alert

window.alert(“输出内容”);

3.在指定位置输出innerHTML

var x=document.getElementById(“id名”);//使用id属性查找元素

x.innerHTML=”输出内容”;//改变内容,写入到HTML元素

4.在控制台上输出

console.log(‘输出内容’);

1、console.log 用于输出普通信息

2、console.info 用于输出提示性信息

3、console.error用于输出错误信息

4、console.warn用于输出警示信息

5、console.debug用于输出调试信息

可以通过在控制台输入console.clear()来实现清空控制台信息。

https://jingyan.baidu.com/article/6dad507505f714a123e36e8a.html

三 . js基本语法

1.语句

  • js程序执行单位为行,也就是一行一行地执行一般,每一行就是一个语句。语句是为了完成某种任务而进行的操作(赋值语句),语句以分号结束,分号前没有任何内容,js引擎将其视为空语句
  • 表达式(需要得出结果)不需要分号结尾,不然js引擎会将其视为语句,这样会产生一些没有意义的语句

2.js用法

  • HTML脚本必须位于标签之间,脚本可放置在body或head标签中
  • 如需在HTML页面中插入脚本,请使用script标签,他会告诉js在何处开始和结束
  • 引入外部脚本
js区分大小写

3.变量

  • 局部变量不声明变量,即不写var,会自动创建全局变量;如果使用var重新声明一个已经存在的变量,是无效的。但第二次声明的时候还进行了赋值,则会覆盖掉前面的值。
  • 如果一个变量没有声明就直接使用,js会报错,告诉你变量未定义
  • JavaScript 是一种动态类型语言,也就是说,变量的类型没有限制,变量可以随时更改类型。
  • 变量是一个名称,字面量是一个值
  • JavaScript 标识符必须以字母、下划线(_)或美元符($)开始。后续的字符可以是字母、数字、下划线或美元符(数字是不允许作为首字符出现的,以便 JavaScript 可以轻易区分开标识符和数字)。
  • undefined:声明变量却没赋值的变量,表示“无定义”
  • 单行用 / / 注释,多行注释用 /* */
  • 当您向变量分配文本值时,应该用双引号或单引号包围这个值。当您向变量赋的值是数值时,不要使用引号。如果您用引号包围数值,该值会被作为文本来处理。
1 .变量类型
  • 值类型
    • 占用空间固定,保存在栈中
    • 保存复制的是值本身
    • 使用typeof检测数据的类型
    • 基本类型数据是值类型
  • 引用类型
    • 占用空间不固定,保存在堆中
    • 保存和复制的是指向对象的一个指针
    • 使用instanceof检测数据的类型
    • 使用new()方法构造出来的对象是引用型的
2.作用域
  • 全局变量
    • 在函数体外定义的变量或者在函数体内部定义的无var的变量
    • 在任何位置都可以调用
  • 局部变量
    • 在函数体内部用var声明的变量或函数的参数变量
    • 在当前函数体内部调用
  • 优先级
    • 同名全局变量 > 参数变量 > 局部变量 > 全局变量
  • 特性
    • 忽略块级作用域
    • 全局变量是全局对象的属性
    • 局部变量是调用对象的属性
    • 作用域链
      • 内层函数可以访问外层函数的局部变量
      • 外层函数不能访问内层函数局部变量
    • 生命周期
      • 全局变量:除非被显示删除,否则一直存在
      • 局部变量:自声明起至函数运行完毕或者显示删除
      • 收回机制
        • 标记清除,引用计数

4.数据类型

1.数字 Number
2.字符串String
  • 由0个或多个16位Unicode字符组成

  • 单引号与双引号不能交叉使用

  • 使用length属性访问字符串长度

    • 转义字符算一个字符
    • 无法精确返回双字节字符长度
  • 字符串一旦被创建,其值将不能修改,若要改变必须销毁原有字符串

  • 不要创建 String 对象。它会拖慢执行速度,并可能产生其他副作用

  • 类型转换

    • toString()使用类型

      ​ 1.number

      ​ 2.boolean

      ​ 3.string

      ​ 4.object

    • eval():计算字符串表达式的值并以数值形式返回

3.布尔Boolean
  • 任何值和布尔值比较时,两边都会转化为Number类型

  • [0]用if判断的时候为true,和布尔值比较的时候转换为0。{x:0}用if判断的时候为true,和布尔值比较的时候转换为NaN

  • 转换为true

    • 任何非空字符串
    • 任何非0的数值
    • 数组和对象(包括空数组和空对象)
  • 转换为false

    • 空字符串
    • 0和NaN
    • null和undefined
4.数组Array
  • 对象Object

  • 空Null

    • 逻辑上null表示一个空对象的指针,使用typeof检测时会返回object
  • 未定义Undefined

    • 使用var声明变量但未初始化
    • 区分空对象指针与尚未定义的变量
    • 对未初始化的变量及未声明的变量使用typeof运算符均会返回undefined
  • undefined与null的关系
    • undefined派生于null因此在使用“==”进行比较的时候会返回true
    • 没有必要将变量值声明为undefined
    • 声明空对象的时候应将其值赋值为null
5.非数值NaN(Not a Number)
  • 任何涉及NaN的操作都将返回NaN

  • NaN与任何数值都不相等包括自身
  • 检测isNaN()

    • 可转换成数值false
    • 不可转换成数值true
6.未定义undefined
  • 变量声明了却没有赋值
  • 调用函数时,应该提供的参数没有提供,该参数等于undefined
  • 对象没有赋值的属性
  • 函数没有返回值,默认返回undefined

5.数值转换

1.Number()
  • Boolean——(true 1)(false 0)
  • null——0
  • undefined / { }———NaN (null是一个表示”无”的对象,转为数值时为0undefined是一个表示”无”的原始值,转为数值时为NaN)
  • String除数字和空字符串(0)外,其余都是NaN
2.解析parseInt(“要解析的字符串”,转换时使用的基数)
  • 忽略前置空格
  • 直接找到第一个非空格字符
    • NaN:不是数字字符或符号
    • 如果是数字字符解析所有后续字符,或一直解析直到遇到非数字字符便结束
3.parseFloat()
  • 从第一个字符开始解析,遇到无效浮点格式后结束
  • 只有第一个小数点有效,忽略前导0
  • 十六进制数始终为0,没有小数点或小数点后全0

6.对象object

  • 一组数据或功能的集合
  • 声明 var o=new Object()
  • 属性和方法
    • Constructor:保存用于创建当前对象的函数
    • hasOwnProperty(propertyName):检测给定属性在当前对象实例中是否存在
    • isPrototypeOf(object)检测传入的对象是否为另一个对象的原型
    • propertyisEnumerable(propertyName)检测给定属性是否能用for-in语句枚举
    • toLocalString()返回对象的字符串表示,该字符串与执行环境的地区对应
    • toString()返回对象的字符串表示
    • valueOf()返回对象的字符串,数值或布尔值表示;通常和toString()的值相同
https://blog.csdn.net/IT_10/article/details/81806665

四 . 数据类型的概述

1.六大数据类型(number,string,boolean,undefined,null,onject)

  • 原始类型(primitive type)
    • 不能再细分,最基本的数据类型
    • number,string,boolean
  • 合成类型(complex type)
    • 可看作一个存放多个原始类型值的容器
    • 狭义对象(object),数组(array),函数(function)
  • undefined和null一般将他们看成两个特殊值
  • 狭义的对象(object)和数组是两种不同的数据组合方式,而函数其实是处理数据的方法。js把函数当成一种数据类型,可以像其他类型的数据一样,进行赋值和传递,这为编程带来了很大的灵活性,体现了js作为“函数式语言”的本质
  • js的所有数据都可以视为广义的对象。不仅数组和函数属于对象,就连原始值也可用对象方式调用,(不过都是隐式转换,就像输入数值都会隐式转换成字符串数值一样)

2.确定值是什么类型的几种方法

1.typeof运算符
  • typeof 123 //“number”
  • typeof ‘123’ //“string”
  • typeof false //“boolean”
  • function f(){} typeof f //“function”
  • typeof undefined //“undefined”(利用这一点,可用来检查一个没有申明的变量而不报错)
  • typeof window / { } / [ ] / null //“object”(表明数组本质上只是一种特殊的对象。null的类型也是object,这是由于历史原因造成的)
2.instanceof运算符
  • 解决typeof没法区分数组和对象的缺陷
  • {}/[] instanceof Object/Array //true
  • (function(0{})) instanceof Function //true
  • 原始类型 instanceof 各种类型 //一般都是false
3.Object.prototype.toString方法
  • 1
    2
    Object.prototype.toString.call([1,2,3])
    '[object Array]
4.应用typeof方法写方法
  • 1
    2
    3
    var toType = function(obj) {
    return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
    }
1
2
3
4
5
6
7
8
9
10
11
toType({a: 4}) // "object"
toType([1, 2, 3]) // "array"
(function() { return toType(arguments) }()) // "arguments"
toType(new ReferenceError()) // "error"
toType(new Date()) // "date"
toType(/a-z/) // "regexp"
toType(Math) // "math"
toType(JSON) // "json"
toType(new Number(4)) // "number"
toType(new String("abc")) // "string"
toType(new Boolean(true)) // "boolean"

五 . JavaScript函数

1.定义方法

  • 静态方法function function nane(){执行代码}
  • 动态匿名方法 var 函数名=new Function([“虚参数列表”],“函数体”);
  • 直接量方法 函数名=function(【虚参列表】){函数体}

2.调用方法

  • 函数作为对象方法调用,会使得 this 的值成为对象本身。

  • call()(传入的参数是一系列的参数值,但是从第二个参数开始) 和 apply() (传入的参数只能是由各参数值组成的数组)是预定义的函数方法。 两个方法可用于调用函数,两个方法的第一个参数必须是对象本身。

  • 在 JavaScript 严格模式(strict mode)下, 在调用函数时第一个参数会成为 this 的值, 即使该参数不是一个对象。

  • 在 JavaScript 非严格模式(non-strict mode)下, 如果第一个参数的值是 null 或 undefined, 它将使用全局对象替代。

  • 在 HTML 中默认的全局对象是 HTML 页面本身,所以函数是属于 HTML 页面。

  • 在浏览器中的页面对象是浏览器窗口(window 对象)。以上函数会自动变为 window 对象的函数。

  • 直接调用 函数名(实参列表)

  • 在连接中调用

  • 在事件中调用 事件类型=“函数名()”

  • 递归调用(在函数体内部调用自身) function 函数名(){代码 函数名();}

  • 构造函数调用

    • 构造函数中 this 关键字没有任何的值。
      this 的值在函数调用时实例化对象(new object)时创建。

    • 如果函数或者方法调用之前带有关键字new,他就构成构造函数调用。凡是没有形参的构造函数调用都可以省略圆括号 var o=new Object;

    • 立即调用函数(IIFE)

      • 一对圆括号()是一种运算符,跟在函数名之后,表示调用该函数

      • (function(){

        statement

        }())

      • 上面代码的圆括号的用法,function之前的左圆括号是必需的,因为如果不写这个左圆括号,JavaScript解释器会试图将关键字function解析为函数声明语句。而使用圆括号,JavaScript解释器才会正确地将其解析为函数定义表达式。

3.常用方法

  • apply:将函数作为对象的方法来调用,将参数传递给该方法
  • call:将函数作为对象的方法来调用,将参数传递给该方法
  • toString:返回函数的字符串表示

4.arguments对象

  • 功能:存放实参的参数列表

  • 特性

    • 仅能在函数体内使用
    • 带有下标属性,但并非数组
    • 函数声明时自动初始化
  • 属性

    • length:获取函数实参的长度

    • callee :返回当前正在指向的对象

    • caller:返回调用当前正在执行函数的函数名

    • name属性:返回紧跟在function关键字后的那个函数名

    • toString方法返回函数的源码

    • eval命令的作用是将字符串当作语句执行,eval没有自己的作用域,都是在当前作用域内执行

      eval(‘var a=1’);

      JavaScript规定,如果使用严格模式,eval内部声明的变量,不会影响到外部作用域。

      (function(){

      ‘use strict’;

      eval(‘var a=1’);

      console.log(a); //ReferenceError: a is not defined

      })();

5.指针标识

  • this:指向当前操作对象

  • callee:指向参数集合所属函数

  • prototype:指向函数附带的原型对象

  • constructor:指向创建该函数的构造函数

  • JavaScript 变量的生命期从它们被声明的时间开始。局部变量会在函数运行以后被删除。全局变量会在页面关闭后被删除。

  • 如果您把值赋给尚未声明的变量,该变量将被自动作为全局变量声明。

6.函数变量提升

  • 全局变量用var命令声明,不管在什么位置声明,变量声明都会被提升头部
  • 函数作用域内部也会产生变量提升

7.闭包

  • JavaScript的函数可以嵌套在其他函数中定义,这样它们就可以访问它们被定义时所处的作用域中的任何变量,这就是JavaScript的闭包。 闭包的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。
  • 闭包的另一个用处,是封装对象的私有属性和私有方法。

8.数组

  • 数组属于一种特殊的对象

  • 数组长度length属性

    • length属性是可写的。如果人为设置一个小于当前成员个数的值,该数组的成员会自动减少到length设置的值。
    • 将数组清空的一个有效方法,就是将length属性设为0。
    • 如果人为设置length大于当前元素个数,则数组的成员数量会增加到这个值,新增的位置都是空位。
    • 在ECMAScript 5中,可以用Object.defineProperty() 让数组的length属性变成只读。
  • 空位

    • 当数组的某个位置是空元素,即两个逗号之间没有任何值,我们称该数组存在空位 var arr=【1,,2】
    • 但是,如果最后一个元素后面有逗号,并不会产生空位。数组直接量的语法允许有可选的结尾的逗号,故[,,]只有两个元素而非三个。
  • 类数组对象

    • 在JavaScript中,有些对象被称为“类数组对象”。意思是,它们看上去很像数组,可以使用length属性,但是它们并不是数组,无法使用一些数组的方法。

    • 由于类数组对象没有继承自Array.prototype,那就不能在它们上面直接调用数组方法。不过我们可以间接的使用Function.call方法调用。

六 . JavaScript错误处理机制

  • javascript解析或执行时,一旦发生错误,引擎就会自动抛出一个错误对象,js提供一个Error构造函数,所有抛出的错误都是这个构造函数的实例 var err=new Error(‘出错了’);err.message

  • Erroe对象的属性

    • message:错误提示信息
    • name:错误名称(非标准属性)
    • stack:错误的堆栈(非标准属性)
  • Error的六大派生对象

    • SyntaxError:是解析代码时发生的错误(变量名错误或者缺少括号)
    • ReferenceError:是引用一个不存在的变量时发生的的错误或者将一个值分配给无法分配的对象,比如对函数的运行结果或者this赋值(console.log()=1)
    • RangeError:是当一个值超过有效范围时发生的错误,主要有几种情况,一是数组长度为负数,二是Number对象的方法参数超出范围,以及函数堆栈超过最大值
      • new Array(-1)
      • (1234).toExponential(21)//toExponential() argument must be between 0 and 20
    • TypeError:是参数或变量不是预期类型时发生的错误。比如,对字符串,布尔值,数值等原始类型的值使用new命令,就会抛出这种错误,因为new命令的参数应该是一个构造函数 new 123
    • URIError:是URI相关函数的参数不正确时抛出的错误,主要涉及encodeURI(),decodeURI(),encodeURIComponent(),decodeURIComponent(),escape(),unescape()
    • EvalError:函数没有被正确执行时抛出EvalError错误,该错误类型已不再ES5中出现,只是为了与以前代码兼容
  • 自定义错误

    function UserError(message){

    this.message=message ||”默认信息”;

    this.name=”UserError”;}

    UserError.prototype=new Error();

    UserError.prototype.constructor=UserError;

  • throw语句:作用是中断程序执行,抛出一个意外或错误,他接受一个表达式作为参数,可以抛出各种值

七 . JavaScript JSON

  • JSON英文全称JavaScript Object Notation

  • 是一种易于理解的独立的语言,也是一种轻量级的数据交换格式

  • JSON使用JavaScript语法,但是JSON格式仅仅是一个文本。文本可以被任何编程语言读取及作为数据传递格式

  • 语法规则

    • 数据以键值对形式出现
    • 数据由逗号分隔
    • 大括号保存对象
    • 方括号保存数组
  • 通常我们从服务器中读取JSON数据,并在网页中显示数据

  • JSON字符串转换为js对象

    • 创建js字符串,字符串为JSON格式的数据

      var text = ‘{ “employees” : [‘ +
      ‘{ “firstName”:”John” , “lastName”:”Doe” },’ +
      ‘{ “firstName”:”Anna” , “lastName”:”Smith” },’ +
      ‘{ “firstName”:”Peter” , “lastName”:”Jones” } ]}’;

    • 然后使用js内置函数JSON.parse()将字符串转化为js对象

    • var obj=JSON.parse(text);

    • 最后在你的页面使用js对象

八 . JavaScript:void(0)的含义

  • void关键字是js中非常重要的关键字,该操作符指定要计算一个表达式但是不返回值

    点我!

  • href=”#”与href=”javascript:void(0)”的区别

    # 包含了一个位置信息,默认的锚是#top 也就是网页的上端。

    而javascript:void(0), 仅仅表示一个死链接。

    在页面很长的时候会使用 # 来定位页面的具体位置,格式为:# + id

    如果你要定义一个死链接请使用 javascript:void(0) 。

  • void()仅仅是代表不返回任何值,但是括号内的表达式还是要运行

九 . 命名规范

  • 变量名应该区分大小写,允许包含字母、数字、美元符号($)和下划线,但第一个字符不允许是数字,不允许包含空格和其他标点符号;

  • 变量命名长度应该尽可能的短,并抓住要点,尽量在变量名中体现出值的类型;

  • 变量名的命名应该是有意义的;

  • 变量名不能为JavaScript中的关键词、保留字全名;

  • 变量名命名方法常见的有匈牙利命名法、驼峰命名法和帕斯卡命名法。

  • 空格与运算符

    通常运算符 ( = + - * / ) 前后需要添加空格:

  • 代码缩进

    通常使用 4 个空格符号来缩进代码块:

    注意:不推荐使用 TAB 键来缩进,因为不同编辑器 TAB 键的解析不一样。

  • 复杂语句的通用规则:

    • 一条语句通常以分号作为结束符。
    • 将左花括号放在第一行的结尾。
    • 左花括号前添加一空格。
    • 将右花括号独立放在一行。
    • 不要以分号结束一个复杂的声明。
  • 对象定义的规则:

    • 将左花括号与类名放在同一行。
    • 冒号与属性值间有个空格。
    • 字符串使用双引号,数字不需要。
    • 最后一个属性-值对后面不要添加逗号。
    • 将右花括号独立放在一行,并以分号作为结束符号。
  • 命名规则
    • 变量和函数为驼峰法( camelCase
    • 全局变量为大写 (UPPERCASE )
    • 常量 (如 PI) 为大写 (UPPERCASE )

十.文档对象模型HTML DOM

DOM HTML tree

  • 通过可编程的对象模型,js能够改变页面中的所有HTML元素,属性,CSS样式,能对页面中的所有事件作出反应

1.找HTML元素

  • 通过id document.getElementById(“id值”);
  • 通过标签名 document.getElementByTagName(“标签名”);
  • 通过类名 document.getElementByClassName(“类名”);

2.节点指针

  • firstChild :获取元素的首个子节点
  • lastChild :获取元素的最后一个子节点
  • 父节点.childNodes :获取元素的子节点列表
  • 兄弟节点.previousSibling:获取已知节点的前一个节点
  • 兄弟节点.nextSibling : 获取已知节点的后一个节点
  • 子节点.parentNode :获取已知节点的父节点

3.创建节点

  • 创建元素节点 document.createElement(元素标签)
  • 创建属性节点 document.createAttribute(元素属性)
  • 创建文本节点 document.createTextNode(文本内容)

4.插入节点

  • 向节点的子节点列表的末尾添加新的子节点 appendChild(所添加的新节点)
  • 在已知的子节点前插入一个新的子节点 insertBefore(所要添加的新节点,已知节点)

img

5.改变HTML元素样式

document.getElementById(id).style.property=new style;

6.添加监听事件

element.addEventListener(event,function,useCapture);

第一个参数就是事件的类型(如“click”或“mousedown”。注意不要使用“on”前缀,是“click”而非“onclick”)

第二个参数就是事件触发时调用的函数

第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的

7.事件冒泡或事件捕获

事件传递有两种方式:冒泡与捕获。

事件传递定义了元素事件触发的顺序。 如果你将

元素插入到

元素中,用户点击

元素, 哪个元素的 “click” 事件先被触发呢?

在冒泡中,内部元素的事件会先被触发,然后再触发外部元素,即:

元素的点击事件先触发,然后会触发

元素的点击事件。

在捕获中,外部元素的事件会先被触发

img

在线工具库:https://123.w3cschool.cn/webtools

一 . js简介

1.概念

  • javascript是世界上最流行的脚本语言。js是属于web的语言,他适合与PC,笔记本电脑,平板电脑和移动电话。ja被设计成向HTNL页面增加交互性。
    • 脚本语言:指的是他不具备开发操作系统的能力,而是只用来编写控制其他大型应用程序(比如浏览器)的“脚本”
  • 通过嵌入HTML来实现各种酷炫的动态效果,为用户提供赏心悦目的浏览效果。所有现代的 HTML 页面都使用 JavaScript,可以用于改进设计、验证表单、检测浏览器、创建cookies等。
  • javaScript 是一种轻量级的编程语言。JavaScript 是可插入 HTML 页面的编程代码。JavaScript 插入 HTML 页面后,可由所有的现代浏览器执行。
  • javascript也是一种嵌入式(embedded)语言。它本身提供的核心语法不算很多,只是用来做一些数学和逻辑运算。js本身不提供任何与I/O(输入/输出)相关的API,主要靠宿主环境(host)提供,所以js只适合嵌入更大型的应用程序环境,去调用宿主环境提供的底层API。目前,已经嵌入JavaScript的宿主环境有多种,最常见的环境就是浏览器,另外还有服务器环境,也就是Node项目
  • 从语法角度看,javascript语言是一种“对象模型”语言。各种宿主环境通过这个模型,描述自己的功能和操作接口,从而通过js控制这些功能。但是,js并不是纯粹的“面型对象语言”,还支持其他编程范式(比如函数式编程)

2.支持编译运行。

  • JavaScript 语言本身,虽然是一种解释型语言,但是在现代浏览器中,JavaScript 都是编译后运行。程序会被高度优化,运行效率接近二进制程序。而且,JavaScript 引擎正在快速发展,性能将越来越好。
  • 此外,还有一种 WebAssembly 格式,它是 JavaScript 引擎的中间码格式,全部都是二进制代码。由于跳过了编译步骤,可以达到接近原生二进制代码的运行速度。各种语言(主要是 C 和 C++)通过编译成 WebAssembly,就可以在浏览器里面运行。

3.事件驱动和非阻塞式设计

  • JavaScript 程序可以采用事件驱动(event-driven)和非阻塞式(non-blocking)设计,在服务器端适合高并发环境,普通的硬件就可以承受很大的访问量。

4.javascript与java的关系

Java javascript
强类型 弱类型(同一变量可以存放不同类型的变量(但是始终存放同一类型是良好的编码习惯)

必须在JAVA虚拟机上运行,且事先需要进行编译 不依托编辑器,在浏览器就可以实现,边解释边执行

二 . 输出

1.直接写入HTML输出流

document.write(“输出内容”); 将内容写入HTML文档

  • 你只能在HTNL输出中使用document.write。如果在文档加载完成后使用该方法,会覆盖整个文档。

2.弹出警告框alert

window.alert(“输出内容”);

3.在指定位置输出innerHTML

var x=document.getElementById(“id名”);//使用id属性查找元素

x.innerHTML=”输出内容”;//改变内容,写入到HTML元素

4.在控制台上输出

console.log(‘输出内容’);

1、console.log 用于输出普通信息

2、console.info 用于输出提示性信息

3、console.error用于输出错误信息

4、console.warn用于输出警示信息

5、console.debug用于输出调试信息

可以通过在控制台输入console.clear()来实现清空控制台信息。

https://jingyan.baidu.com/article/6dad507505f714a123e36e8a.html

三 . js基本语法

1.语句

  • js程序执行单位为行,也就是一行一行地执行一般,每一行就是一个语句。语句是为了完成某种任务而进行的操作(赋值语句),语句以分号结束,分号前没有任何内容,js引擎将其视为空语句
  • 表达式(需要得出结果)不需要分号结尾,不然js引擎会将其视为语句,这样会产生一些没有意义的语句

2.js用法

  • HTML脚本必须位于标签之间,脚本可放置在body或head标签中
  • 如需在HTML页面中插入脚本,请使用script标签,他会告诉js在何处开始和结束
  • 引入外部脚本
js区分大小写

3.变量

  • 局部变量不声明变量,即不写var,会自动创建全局变量;如果使用var重新声明一个已经存在的变量,是无效的。但第二次声明的时候还进行了赋值,则会覆盖掉前面的值。
  • 如果一个变量没有声明就直接使用,js会报错,告诉你变量未定义
  • JavaScript 是一种动态类型语言,也就是说,变量的类型没有限制,变量可以随时更改类型。
  • 变量是一个名称,字面量是一个值
  • JavaScript 标识符必须以字母、下划线(_)或美元符($)开始。后续的字符可以是字母、数字、下划线或美元符(数字是不允许作为首字符出现的,以便 JavaScript 可以轻易区分开标识符和数字)。
  • undefined:声明变量却没赋值的变量,表示“无定义”
  • 单行用 / / 注释,多行注释用 /* */
  • 当您向变量分配文本值时,应该用双引号或单引号包围这个值。当您向变量赋的值是数值时,不要使用引号。如果您用引号包围数值,该值会被作为文本来处理。
1 .变量类型
  • 值类型
    • 占用空间固定,保存在栈中
    • 保存复制的是值本身
    • 使用typeof检测数据的类型
    • 基本类型数据是值类型
  • 引用类型
    • 占用空间不固定,保存在堆中
    • 保存和复制的是指向对象的一个指针
    • 使用instanceof检测数据的类型
    • 使用new()方法构造出来的对象是引用型的
2.作用域
  • 全局变量
    • 在函数体外定义的变量或者在函数体内部定义的无var的变量
    • 在任何位置都可以调用
  • 局部变量
    • 在函数体内部用var声明的变量或函数的参数变量
    • 在当前函数体内部调用
  • 优先级
    • 同名全局变量 > 参数变量 > 局部变量 > 全局变量
  • 特性
    • 忽略块级作用域
    • 全局变量是全局对象的属性
    • 局部变量是调用对象的属性
    • 作用域链
      • 内层函数可以访问外层函数的局部变量
      • 外层函数不能访问内层函数局部变量
    • 生命周期
      • 全局变量:除非被显示删除,否则一直存在
      • 局部变量:自声明起至函数运行完毕或者显示删除
      • 收回机制
        • 标记清除,引用计数

4.数据类型

1.数字 Number
2.字符串String
  • 由0个或多个16位Unicode字符组成

  • 单引号与双引号不能交叉使用

  • 使用length属性访问字符串长度

    • 转义字符算一个字符
    • 无法精确返回双字节字符长度
  • 字符串一旦被创建,其值将不能修改,若要改变必须销毁原有字符串

  • 不要创建 String 对象。它会拖慢执行速度,并可能产生其他副作用

  • 类型转换

    • toString()使用类型

      ​ 1.number

      ​ 2.boolean

      ​ 3.string

      ​ 4.object

    • eval():计算字符串表达式的值并以数值形式返回

3.布尔Boolean
  • 任何值和布尔值比较时,两边都会转化为Number类型

  • [0]用if判断的时候为true,和布尔值比较的时候转换为0。{x:0}用if判断的时候为true,和布尔值比较的时候转换为NaN

  • 转换为true

    • 任何非空字符串
    • 任何非0的数值
    • 数组和对象(包括空数组和空对象)
  • 转换为false

    • 空字符串
    • 0和NaN
    • null和undefined
4.数组Array
  • 对象Object

  • 空Null

    • 逻辑上null表示一个空对象的指针,使用typeof检测时会返回object
  • 未定义Undefined

    • 使用var声明变量但未初始化
    • 区分空对象指针与尚未定义的变量
    • 对未初始化的变量及未声明的变量使用typeof运算符均会返回undefined
  • undefined与null的关系
    • undefined派生于null因此在使用“==”进行比较的时候会返回true
    • 没有必要将变量值声明为undefined
    • 声明空对象的时候应将其值赋值为null
5.非数值NaN(Not a Number)
  • 任何涉及NaN的操作都将返回NaN

  • NaN与任何数值都不相等包括自身
  • 检测isNaN()

    • 可转换成数值false
    • 不可转换成数值true
6.未定义undefined
  • 变量声明了却没有赋值
  • 调用函数时,应该提供的参数没有提供,该参数等于undefined
  • 对象没有赋值的属性
  • 函数没有返回值,默认返回undefined

5.数值转换

1.Number()
  • Boolean——(true 1)(false 0)
  • null——0
  • undefined / { }———NaN (null是一个表示”无”的对象,转为数值时为0undefined是一个表示”无”的原始值,转为数值时为NaN)
  • String除数字和空字符串(0)外,其余都是NaN
2.解析parseInt(“要解析的字符串”,转换时使用的基数)
  • 忽略前置空格
  • 直接找到第一个非空格字符
    • NaN:不是数字字符或符号
    • 如果是数字字符解析所有后续字符,或一直解析直到遇到非数字字符便结束
3.parseFloat()
  • 从第一个字符开始解析,遇到无效浮点格式后结束
  • 只有第一个小数点有效,忽略前导0
  • 十六进制数始终为0,没有小数点或小数点后全0

6.对象object

  • 一组数据或功能的集合
  • 声明 var o=new Object()
  • 属性和方法
    • Constructor:保存用于创建当前对象的函数
    • hasOwnProperty(propertyName):检测给定属性在当前对象实例中是否存在
    • isPrototypeOf(object)检测传入的对象是否为另一个对象的原型
    • propertyisEnumerable(propertyName)检测给定属性是否能用for-in语句枚举
    • toLocalString()返回对象的字符串表示,该字符串与执行环境的地区对应
    • toString()返回对象的字符串表示
    • valueOf()返回对象的字符串,数值或布尔值表示;通常和toString()的值相同
https://blog.csdn.net/IT_10/article/details/81806665

四 . 数据类型的概述

1.六大数据类型(number,string,boolean,undefined,null,onject)

  • 原始类型(primitive type)
    • 不能再细分,最基本的数据类型
    • number,string,boolean
  • 合成类型(complex type)
    • 可看作一个存放多个原始类型值的容器
    • 狭义对象(object),数组(array),函数(function)
  • undefined和null一般将他们看成两个特殊值
  • 狭义的对象(object)和数组是两种不同的数据组合方式,而函数其实是处理数据的方法。js把函数当成一种数据类型,可以像其他类型的数据一样,进行赋值和传递,这为编程带来了很大的灵活性,体现了js作为“函数式语言”的本质
  • js的所有数据都可以视为广义的对象。不仅数组和函数属于对象,就连原始值也可用对象方式调用,(不过都是隐式转换,就像输入数值都会隐式转换成字符串数值一样)

2.确定值是什么类型的几种方法

1.typeof运算符
  • typeof 123 //“number”
  • typeof ‘123’ //“string”
  • typeof false //“boolean”
  • function f(){} typeof f //“function”
  • typeof undefined //“undefined”(利用这一点,可用来检查一个没有申明的变量而不报错)
  • typeof window / { } / [ ] / null //“object”(表明数组本质上只是一种特殊的对象。null的类型也是object,这是由于历史原因造成的)
2.instanceof运算符
  • 解决typeof没法区分数组和对象的缺陷
  • {}/[] instanceof Object/Array //true
  • (function(0{})) instanceof Function //true
  • 原始类型 instanceof 各种类型 //一般都是false
3.Object.prototype.toString方法
  • 1
    2
    Object.prototype.toString.call([1,2,3])
    '[object Array]
4.应用typeof方法写方法
  • 1
    2
    3
    var toType = function(obj) {
    return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
    }
1
2
3
4
5
6
7
8
9
10
11
toType({a: 4}) // "object"
toType([1, 2, 3]) // "array"
(function() { return toType(arguments) }()) // "arguments"
toType(new ReferenceError()) // "error"
toType(new Date()) // "date"
toType(/a-z/) // "regexp"
toType(Math) // "math"
toType(JSON) // "json"
toType(new Number(4)) // "number"
toType(new String("abc")) // "string"
toType(new Boolean(true)) // "boolean"

五 . JavaScript函数

1.定义方法

  • 静态方法function function nane(){执行代码}
  • 动态匿名方法 var 函数名=new Function([“虚参数列表”],“函数体”);
  • 直接量方法 函数名=function(【虚参列表】){函数体}

2.调用方法

  • 函数作为对象方法调用,会使得 this 的值成为对象本身。

  • call()(传入的参数是一系列的参数值,但是从第二个参数开始) 和 apply() (传入的参数只能是由各参数值组成的数组)是预定义的函数方法。 两个方法可用于调用函数,两个方法的第一个参数必须是对象本身。

  • 在 JavaScript 严格模式(strict mode)下, 在调用函数时第一个参数会成为 this 的值, 即使该参数不是一个对象。

  • 在 JavaScript 非严格模式(non-strict mode)下, 如果第一个参数的值是 null 或 undefined, 它将使用全局对象替代。

  • 在 HTML 中默认的全局对象是 HTML 页面本身,所以函数是属于 HTML 页面。

  • 在浏览器中的页面对象是浏览器窗口(window 对象)。以上函数会自动变为 window 对象的函数。

  • 直接调用 函数名(实参列表)

  • 在连接中调用

  • 在事件中调用 事件类型=“函数名()”

  • 递归调用(在函数体内部调用自身) function 函数名(){代码 函数名();}

  • 构造函数调用

    • 构造函数中 this 关键字没有任何的值。
      this 的值在函数调用时实例化对象(new object)时创建。

    • 如果函数或者方法调用之前带有关键字new,他就构成构造函数调用。凡是没有形参的构造函数调用都可以省略圆括号 var o=new Object;

    • 立即调用函数(IIFE)

      • 一对圆括号()是一种运算符,跟在函数名之后,表示调用该函数

      • (function(){

        statement

        }())

      • 上面代码的圆括号的用法,function之前的左圆括号是必需的,因为如果不写这个左圆括号,JavaScript解释器会试图将关键字function解析为函数声明语句。而使用圆括号,JavaScript解释器才会正确地将其解析为函数定义表达式。

3.常用方法

  • apply:将函数作为对象的方法来调用,将参数传递给该方法
  • call:将函数作为对象的方法来调用,将参数传递给该方法
  • toString:返回函数的字符串表示

4.arguments对象

  • 功能:存放实参的参数列表

  • 特性

    • 仅能在函数体内使用
    • 带有下标属性,但并非数组
    • 函数声明时自动初始化
  • 属性

    • length:获取函数实参的长度

    • callee :返回当前正在指向的对象

    • caller:返回调用当前正在执行函数的函数名

    • name属性:返回紧跟在function关键字后的那个函数名

    • toString方法返回函数的源码

    • eval命令的作用是将字符串当作语句执行,eval没有自己的作用域,都是在当前作用域内执行

      eval(‘var a=1’);

      JavaScript规定,如果使用严格模式,eval内部声明的变量,不会影响到外部作用域。

      (function(){

      ‘use strict’;

      eval(‘var a=1’);

      console.log(a); //ReferenceError: a is not defined

      })();

5.指针标识

  • this:指向当前操作对象

  • callee:指向参数集合所属函数

  • prototype:指向函数附带的原型对象

  • constructor:指向创建该函数的构造函数

  • JavaScript 变量的生命期从它们被声明的时间开始。局部变量会在函数运行以后被删除。全局变量会在页面关闭后被删除。

  • 如果您把值赋给尚未声明的变量,该变量将被自动作为全局变量声明。

6.函数变量提升

  • 全局变量用var命令声明,不管在什么位置声明,变量声明都会被提升头部
  • 函数作用域内部也会产生变量提升

7.闭包

  • JavaScript的函数可以嵌套在其他函数中定义,这样它们就可以访问它们被定义时所处的作用域中的任何变量,这就是JavaScript的闭包。 闭包的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。
  • 闭包的另一个用处,是封装对象的私有属性和私有方法。

8.数组

  • 数组属于一种特殊的对象

  • 数组长度length属性

    • length属性是可写的。如果人为设置一个小于当前成员个数的值,该数组的成员会自动减少到length设置的值。
    • 将数组清空的一个有效方法,就是将length属性设为0。
    • 如果人为设置length大于当前元素个数,则数组的成员数量会增加到这个值,新增的位置都是空位。
    • 在ECMAScript 5中,可以用Object.defineProperty() 让数组的length属性变成只读。
  • 空位

    • 当数组的某个位置是空元素,即两个逗号之间没有任何值,我们称该数组存在空位 var arr=【1,,2】
    • 但是,如果最后一个元素后面有逗号,并不会产生空位。数组直接量的语法允许有可选的结尾的逗号,故[,,]只有两个元素而非三个。
  • 类数组对象

    • 在JavaScript中,有些对象被称为“类数组对象”。意思是,它们看上去很像数组,可以使用length属性,但是它们并不是数组,无法使用一些数组的方法。

    • 由于类数组对象没有继承自Array.prototype,那就不能在它们上面直接调用数组方法。不过我们可以间接的使用Function.call方法调用。

六 . JavaScript错误处理机制

  • javascript解析或执行时,一旦发生错误,引擎就会自动抛出一个错误对象,js提供一个Error构造函数,所有抛出的错误都是这个构造函数的实例 var err=new Error(‘出错了’);err.message

  • Erroe对象的属性

    • message:错误提示信息
    • name:错误名称(非标准属性)
    • stack:错误的堆栈(非标准属性)
  • Error的六大派生对象

    • SyntaxError:是解析代码时发生的错误(变量名错误或者缺少括号)
    • ReferenceError:是引用一个不存在的变量时发生的的错误或者将一个值分配给无法分配的对象,比如对函数的运行结果或者this赋值(console.log()=1)
    • RangeError:是当一个值超过有效范围时发生的错误,主要有几种情况,一是数组长度为负数,二是Number对象的方法参数超出范围,以及函数堆栈超过最大值
      • new Array(-1)
      • (1234).toExponential(21)//toExponential() argument must be between 0 and 20
    • TypeError:是参数或变量不是预期类型时发生的错误。比如,对字符串,布尔值,数值等原始类型的值使用new命令,就会抛出这种错误,因为new命令的参数应该是一个构造函数 new 123
    • URIError:是URI相关函数的参数不正确时抛出的错误,主要涉及encodeURI(),decodeURI(),encodeURIComponent(),decodeURIComponent(),escape(),unescape()
    • EvalError:函数没有被正确执行时抛出EvalError错误,该错误类型已不再ES5中出现,只是为了与以前代码兼容
  • 自定义错误

    function UserError(message){

    this.message=message ||”默认信息”;

    this.name=”UserError”;}

    UserError.prototype=new Error();

    UserError.prototype.constructor=UserError;

  • throw语句:作用是中断程序执行,抛出一个意外或错误,他接受一个表达式作为参数,可以抛出各种值

七 . JavaScript JSON

  • JSON英文全称JavaScript Object Notation

  • 是一种易于理解的独立的语言,也是一种轻量级的数据交换格式

  • JSON使用JavaScript语法,但是JSON格式仅仅是一个文本。文本可以被任何编程语言读取及作为数据传递格式

  • 语法规则

    • 数据以键值对形式出现
    • 数据由逗号分隔
    • 大括号保存对象
    • 方括号保存数组
  • 通常我们从服务器中读取JSON数据,并在网页中显示数据

  • JSON字符串转换为js对象

    • 创建js字符串,字符串为JSON格式的数据

      var text = ‘{ “employees” : [‘ +
      ‘{ “firstName”:”John” , “lastName”:”Doe” },’ +
      ‘{ “firstName”:”Anna” , “lastName”:”Smith” },’ +
      ‘{ “firstName”:”Peter” , “lastName”:”Jones” } ]}’;

    • 然后使用js内置函数JSON.parse()将字符串转化为js对象

    • var obj=JSON.parse(text);

    • 最后在你的页面使用js对象

八 . JavaScript:void(0)的含义

  • void关键字是js中非常重要的关键字,该操作符指定要计算一个表达式但是不返回值

    点我!

  • href=”#”与href=”javascript:void(0)”的区别

    # 包含了一个位置信息,默认的锚是#top 也就是网页的上端。

    而javascript:void(0), 仅仅表示一个死链接。

    在页面很长的时候会使用 # 来定位页面的具体位置,格式为:# + id

    如果你要定义一个死链接请使用 javascript:void(0) 。

  • void()仅仅是代表不返回任何值,但是括号内的表达式还是要运行

九 . 命名规范

  • 变量名应该区分大小写,允许包含字母、数字、美元符号($)和下划线,但第一个字符不允许是数字,不允许包含空格和其他标点符号;

  • 变量命名长度应该尽可能的短,并抓住要点,尽量在变量名中体现出值的类型;

  • 变量名的命名应该是有意义的;

  • 变量名不能为JavaScript中的关键词、保留字全名;

  • 变量名命名方法常见的有匈牙利命名法、驼峰命名法和帕斯卡命名法。

  • 空格与运算符

    通常运算符 ( = + - * / ) 前后需要添加空格:

  • 代码缩进

    通常使用 4 个空格符号来缩进代码块:

    注意:不推荐使用 TAB 键来缩进,因为不同编辑器 TAB 键的解析不一样。

  • 复杂语句的通用规则:

    • 一条语句通常以分号作为结束符。
    • 将左花括号放在第一行的结尾。
    • 左花括号前添加一空格。
    • 将右花括号独立放在一行。
    • 不要以分号结束一个复杂的声明。
  • 对象定义的规则:

    • 将左花括号与类名放在同一行。
    • 冒号与属性值间有个空格。
    • 字符串使用双引号,数字不需要。
    • 最后一个属性-值对后面不要添加逗号。
    • 将右花括号独立放在一行,并以分号作为结束符号。
  • 命名规则
    • 变量和函数为驼峰法( camelCase
    • 全局变量为大写 (UPPERCASE )
    • 常量 (如 PI) 为大写 (UPPERCASE )

十.文档对象模型HTML DOM

DOM HTML tree

  • 通过可编程的对象模型,js能够改变页面中的所有HTML元素,属性,CSS样式,能对页面中的所有事件作出反应

1.找HTML元素

  • 通过id document.getElementById(“id值”);
  • 通过标签名 document.getElementByTagName(“标签名”);
  • 通过类名 document.getElementByClassName(“类名”);

2.节点指针

  • firstChild :获取元素的首个子节点
  • lastChild :获取元素的最后一个子节点
  • 父节点.childNodes :获取元素的子节点列表
  • 兄弟节点.previousSibling:获取已知节点的前一个节点
  • 兄弟节点.nextSibling : 获取已知节点的后一个节点
  • 子节点.parentNode :获取已知节点的父节点

3.创建节点

  • 创建元素节点 document.createElement(元素标签)
  • 创建属性节点 document.createAttribute(元素属性)
  • 创建文本节点 document.createTextNode(文本内容)

4.插入节点

  • 向节点的子节点列表的末尾添加新的子节点 appendChild(所添加的新节点)
  • 在已知的子节点前插入一个新的子节点 insertBefore(所要添加的新节点,已知节点)

img

5.改变HTML元素样式

document.getElementById(id).style.property=new style;

6.添加监听事件

element.addEventListener(event,function,useCapture);

第一个参数就是事件的类型(如“click”或“mousedown”。注意不要使用“on”前缀,是“click”而非“onclick”)

第二个参数就是事件触发时调用的函数

第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的

7.事件冒泡或事件捕获?

事件传递有两种方式:冒泡与捕获。

事件传递定义了元素事件触发的顺序。 如果你将

元素插入到

元素中,用户点击

元素, 哪个元素的 “click” 事件先被触发呢?

在冒泡中,内部元素的事件会先被触发,然后再触发外部元素,即:

元素的点击事件先触发,然后会触发

元素的点击事件。

在捕获中,外部元素的事件会先被触发

img

在线工具库:https://123.w3cschool.cn/webtools

一 . js简介

1.概念

  • javascript是世界上最流行的脚本语言。js是属于web的语言,他适合与PC,笔记本电脑,平板电脑和移动电话。ja被设计成向HTNL页面增加交互性。
    • 脚本语言:指的是他不具备开发操作系统的能力,而是只用来编写控制其他大型应用程序(比如浏览器)的“脚本”
  • 通过嵌入HTML来实现各种酷炫的动态效果,为用户提供赏心悦目的浏览效果。所有现代的 HTML 页面都使用 JavaScript,可以用于改进设计、验证表单、检测浏览器、创建cookies等。
  • javaScript 是一种轻量级的编程语言。JavaScript 是可插入 HTML 页面的编程代码。JavaScript 插入 HTML 页面后,可由所有的现代浏览器执行。
  • javascript也是一种嵌入式(embedded)语言。它本身提供的核心语法不算很多,只是用来做一些数学和逻辑运算。js本身不提供任何与I/O(输入/输出)相关的API,主要靠宿主环境(host)提供,所以js只适合嵌入更大型的应用程序环境,去调用宿主环境提供的底层API。目前,已经嵌入JavaScript的宿主环境有多种,最常见的环境就是浏览器,另外还有服务器环境,也就是Node项目
  • 从语法角度看,javascript语言是一种“对象模型”语言。各种宿主环境通过这个模型,描述自己的功能和操作接口,从而通过js控制这些功能。但是,js并不是纯粹的“面型对象语言”,还支持其他编程范式(比如函数式编程)

2.支持编译运行。

  • JavaScript 语言本身,虽然是一种解释型语言,但是在现代浏览器中,JavaScript 都是编译后运行。程序会被高度优化,运行效率接近二进制程序。而且,JavaScript 引擎正在快速发展,性能将越来越好。
  • 此外,还有一种 WebAssembly 格式,它是 JavaScript 引擎的中间码格式,全部都是二进制代码。由于跳过了编译步骤,可以达到接近原生二进制代码的运行速度。各种语言(主要是 C 和 C++)通过编译成 WebAssembly,就可以在浏览器里面运行。

3.事件驱动和非阻塞式设计

  • JavaScript 程序可以采用事件驱动(event-driven)和非阻塞式(non-blocking)设计,在服务器端适合高并发环境,普通的硬件就可以承受很大的访问量。

4.javascript与java的关系

Java javascript
强类型 弱类型(同一变量可以存放不同类型的变量(但是始终存放同一类型是良好的编码习惯)

必须在JAVA虚拟机上运行,且事先需要进行编译 不依托编辑器,在浏览器就可以实现,边解释边执行

二 . 输出

1.直接写入HTML输出流

document.write(“输出内容”); 将内容写入HTML文档

  • 你只能在HTNL输出中使用document.write。如果在文档加载完成后使用该方法,会覆盖整个文档。

2.弹出警告框alert

window.alert(“输出内容”);

3.在指定位置输出innerHTML

var x=document.getElementById(“id名”);//使用id属性查找元素

x.innerHTML=”输出内容”;//改变内容,写入到HTML元素

4.在控制台上输出

console.log(‘输出内容’);

1、console.log 用于输出普通信息

2、console.info 用于输出提示性信息

3、console.error用于输出错误信息

4、console.warn用于输出警示信息

5、console.debug用于输出调试信息

可以通过在控制台输入console.clear()来实现清空控制台信息。

https://jingyan.baidu.com/article/6dad507505f714a123e36e8a.html

三 . js基本语法

1.语句

  • js程序执行单位为行,也就是一行一行地执行一般,每一行就是一个语句。语句是为了完成某种任务而进行的操作(赋值语句),语句以分号结束,分号前没有任何内容,js引擎将其视为空语句
  • 表达式(需要得出结果)不需要分号结尾,不然js引擎会将其视为语句,这样会产生一些没有意义的语句

2.js用法

  • HTML脚本必须位于标签之间,脚本可放置在body或head标签中
  • 如需在HTML页面中插入脚本,请使用script标签,他会告诉js在何处开始和结束
  • 引入外部脚本
js区分大小写

3.变量

  • 局部变量不声明变量,即不写var,会自动创建全局变量;如果使用var重新声明一个已经存在的变量,是无效的。但第二次声明的时候还进行了赋值,则会覆盖掉前面的值。
  • 如果一个变量没有声明就直接使用,js会报错,告诉你变量未定义
  • JavaScript 是一种动态类型语言,也就是说,变量的类型没有限制,变量可以随时更改类型。
  • 变量是一个名称,字面量是一个值
  • JavaScript 标识符必须以字母、下划线(_)或美元符($)开始。后续的字符可以是字母、数字、下划线或美元符(数字是不允许作为首字符出现的,以便 JavaScript 可以轻易区分开标识符和数字)。
  • undefined:声明变量却没赋值的变量,表示“无定义”
  • 单行用 / / 注释,多行注释用 /* */
  • 当您向变量分配文本值时,应该用双引号或单引号包围这个值。当您向变量赋的值是数值时,不要使用引号。如果您用引号包围数值,该值会被作为文本来处理。
1 .变量类型
  • 值类型
    • 占用空间固定,保存在栈中
    • 保存复制的是值本身
    • 使用typeof检测数据的类型
    • 基本类型数据是值类型
  • 引用类型
    • 占用空间不固定,保存在堆中
    • 保存和复制的是指向对象的一个指针
    • 使用instanceof检测数据的类型
    • 使用new()方法构造出来的对象是引用型的
2.作用域
  • 全局变量
    • 在函数体外定义的变量或者在函数体内部定义的无var的变量
    • 在任何位置都可以调用
  • 局部变量
    • 在函数体内部用var声明的变量或函数的参数变量
    • 在当前函数体内部调用
  • 优先级
    • 同名全局变量 > 参数变量 > 局部变量 > 全局变量
  • 特性
    • 忽略块级作用域
    • 全局变量是全局对象的属性
    • 局部变量是调用对象的属性
    • 作用域链
      • 内层函数可以访问外层函数的局部变量
      • 外层函数不能访问内层函数局部变量
    • 生命周期
      • 全局变量:除非被显示删除,否则一直存在
      • 局部变量:自声明起至函数运行完毕或者显示删除
      • 收回机制
        • 标记清除,引用计数

4.数据类型

1.数字 Number
2.字符串String
  • 由0个或多个16位Unicode字符组成

  • 单引号与双引号不能交叉使用

  • 使用length属性访问字符串长度

    • 转义字符算一个字符
    • 无法精确返回双字节字符长度
  • 字符串一旦被创建,其值将不能修改,若要改变必须销毁原有字符串

  • 不要创建 String 对象。它会拖慢执行速度,并可能产生其他副作用

  • 类型转换

    • toString()使用类型

      ​ 1.number

      ​ 2.boolean

      ​ 3.string

      ​ 4.object

    • eval():计算字符串表达式的值并以数值形式返回

3.布尔Boolean
  • 任何值和布尔值比较时,两边都会转化为Number类型

  • [0]用if判断的时候为true,和布尔值比较的时候转换为0。{x:0}用if判断的时候为true,和布尔值比较的时候转换为NaN

  • 转换为true

    • 任何非空字符串
    • 任何非0的数值
    • 数组和对象(包括空数组和空对象)
  • 转换为false

    • 空字符串
    • 0和NaN
    • null和undefined
4.数组Array
  • 对象Object

  • 空Null

    • 逻辑上null表示一个空对象的指针,使用typeof检测时会返回object
  • 未定义Undefined

    • 使用var声明变量但未初始化
    • 区分空对象指针与尚未定义的变量
    • 对未初始化的变量及未声明的变量使用typeof运算符均会返回undefined
  • undefined与null的关系
    • undefined派生于null因此在使用“==”进行比较的时候会返回true
    • 没有必要将变量值声明为undefined
    • 声明空对象的时候应将其值赋值为null
5.非数值NaN(Not a Number)
  • 任何涉及NaN的操作都将返回NaN

  • NaN与任何数值都不相等包括自身
  • 检测isNaN()

    • 可转换成数值false
    • 不可转换成数值true
6.未定义undefined
  • 变量声明了却没有赋值
  • 调用函数时,应该提供的参数没有提供,该参数等于undefined
  • 对象没有赋值的属性
  • 函数没有返回值,默认返回undefined

5.数值转换

1.Number()
  • Boolean——(true 1)(false 0)
  • null——0
  • undefined / { }———NaN (null是一个表示”无”的对象,转为数值时为0undefined是一个表示”无”的原始值,转为数值时为NaN)
  • String除数字和空字符串(0)外,其余都是NaN
2.解析parseInt(“要解析的字符串”,转换时使用的基数)
  • 忽略前置空格
  • 直接找到第一个非空格字符
    • NaN:不是数字字符或符号
    • 如果是数字字符解析所有后续字符,或一直解析直到遇到非数字字符便结束
3.parseFloat()
  • 从第一个字符开始解析,遇到无效浮点格式后结束
  • 只有第一个小数点有效,忽略前导0
  • 十六进制数始终为0,没有小数点或小数点后全0

6.对象object

  • 一组数据或功能的集合
  • 声明 var o=new Object()
  • 属性和方法
    • Constructor:保存用于创建当前对象的函数
    • hasOwnProperty(propertyName):检测给定属性在当前对象实例中是否存在
    • isPrototypeOf(object)检测传入的对象是否为另一个对象的原型
    • propertyisEnumerable(propertyName)检测给定属性是否能用for-in语句枚举
    • toLocalString()返回对象的字符串表示,该字符串与执行环境的地区对应
    • toString()返回对象的字符串表示
    • valueOf()返回对象的字符串,数值或布尔值表示;通常和toString()的值相同
https://blog.csdn.net/IT_10/article/details/81806665

四 . 数据类型的概述

1.六大数据类型(number,string,boolean,undefined,null,onject)

  • 原始类型(primitive type)
    • 不能再细分,最基本的数据类型
    • number,string,boolean
  • 合成类型(complex type)
    • 可看作一个存放多个原始类型值的容器
    • 狭义对象(object),数组(array),函数(function)
  • undefined和null一般将他们看成两个特殊值
  • 狭义的对象(object)和数组是两种不同的数据组合方式,而函数其实是处理数据的方法。js把函数当成一种数据类型,可以像其他类型的数据一样,进行赋值和传递,这为编程带来了很大的灵活性,体现了js作为“函数式语言”的本质
  • js的所有数据都可以视为广义的对象。不仅数组和函数属于对象,就连原始值也可用对象方式调用,(不过都是隐式转换,就像输入数值都会隐式转换成字符串数值一样)

2.确定值是什么类型的几种方法

1.typeof运算符
  • typeof 123 //“number”
  • typeof ‘123’ //“string”
  • typeof false //“boolean”
  • function f(){} typeof f //“function”
  • typeof undefined //“undefined”(利用这一点,可用来检查一个没有申明的变量而不报错)
  • typeof window / { } / [ ] / null //“object”(表明数组本质上只是一种特殊的对象。null的类型也是object,这是由于历史原因造成的)
2.instanceof运算符
  • 解决typeof没法区分数组和对象的缺陷
  • {}/[] instanceof Object/Array //true
  • (function(0{})) instanceof Function //true
  • 原始类型 instanceof 各种类型 //一般都是false
3.Object.prototype.toString方法
  • 1
    2
    Object.prototype.toString.call([1,2,3])
    '[object Array]
4.应用typeof方法写方法
  • 1
    2
    3
    var toType = function(obj) {
    return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
    }
1
2
3
4
5
6
7
8
9
10
11
toType({a: 4}) // "object"
toType([1, 2, 3]) // "array"
(function() { return toType(arguments) }()) // "arguments"
toType(new ReferenceError()) // "error"
toType(new Date()) // "date"
toType(/a-z/) // "regexp"
toType(Math) // "math"
toType(JSON) // "json"
toType(new Number(4)) // "number"
toType(new String("abc")) // "string"
toType(new Boolean(true)) // "boolean"

五 . JavaScript函数

1.定义方法

  • 静态方法function function nane(){执行代码}
  • 动态匿名方法 var 函数名=new Function([“虚参数列表”],“函数体”);
  • 直接量方法 函数名=function(【虚参列表】){函数体}

2.调用方法

  • 函数作为对象方法调用,会使得 this 的值成为对象本身。

  • call()(传入的参数是一系列的参数值,但是从第二个参数开始) 和 apply() (传入的参数只能是由各参数值组成的数组)是预定义的函数方法。 两个方法可用于调用函数,两个方法的第一个参数必须是对象本身。

  • 在 JavaScript 严格模式(strict mode)下, 在调用函数时第一个参数会成为 this 的值, 即使该参数不是一个对象。

  • 在 JavaScript 非严格模式(non-strict mode)下, 如果第一个参数的值是 null 或 undefined, 它将使用全局对象替代。

  • 在 HTML 中默认的全局对象是 HTML 页面本身,所以函数是属于 HTML 页面。

  • 在浏览器中的页面对象是浏览器窗口(window 对象)。以上函数会自动变为 window 对象的函数。

  • 直接调用 函数名(实参列表)

  • 在连接中调用

  • 在事件中调用 事件类型=“函数名()”

  • 递归调用(在函数体内部调用自身) function 函数名(){代码 函数名();}

  • 构造函数调用

    • 构造函数中 this 关键字没有任何的值。
      this 的值在函数调用时实例化对象(new object)时创建。

    • 如果函数或者方法调用之前带有关键字new,他就构成构造函数调用。凡是没有形参的构造函数调用都可以省略圆括号 var o=new Object;

    • 立即调用函数(IIFE)

      • 一对圆括号()是一种运算符,跟在函数名之后,表示调用该函数

      • (function(){

        statement

        }())

      • 上面代码的圆括号的用法,function之前的左圆括号是必需的,因为如果不写这个左圆括号,JavaScript解释器会试图将关键字function解析为函数声明语句。而使用圆括号,JavaScript解释器才会正确地将其解析为函数定义表达式。

3.常用方法

  • apply:将函数作为对象的方法来调用,将参数传递给该方法
  • call:将函数作为对象的方法来调用,将参数传递给该方法
  • toString:返回函数的字符串表示

4.arguments对象

  • 功能:存放实参的参数列表

  • 特性

    • 仅能在函数体内使用
    • 带有下标属性,但并非数组
    • 函数声明时自动初始化
  • 属性

    • length:获取函数实参的长度

    • callee :返回当前正在指向的对象

    • caller:返回调用当前正在执行函数的函数名

    • name属性:返回紧跟在function关键字后的那个函数名

    • toString方法返回函数的源码

    • eval命令的作用是将字符串当作语句执行,eval没有自己的作用域,都是在当前作用域内执行

      eval(‘var a=1’);

      JavaScript规定,如果使用严格模式,eval内部声明的变量,不会影响到外部作用域。

      (function(){

      ‘use strict’;

      eval(‘var a=1’);

      console.log(a); //ReferenceError: a is not defined

      })();

5.指针标识

  • this:指向当前操作对象

  • callee:指向参数集合所属函数

  • prototype:指向函数附带的原型对象

  • constructor:指向创建该函数的构造函数

  • JavaScript 变量的生命期从它们被声明的时间开始。局部变量会在函数运行以后被删除。全局变量会在页面关闭后被删除。

  • 如果您把值赋给尚未声明的变量,该变量将被自动作为全局变量声明。

6.函数变量提升

  • 全局变量用var命令声明,不管在什么位置声明,变量声明都会被提升头部
  • 函数作用域内部也会产生变量提升

7.闭包

  • JavaScript的函数可以嵌套在其他函数中定义,这样它们就可以访问它们被定义时所处的作用域中的任何变量,这就是JavaScript的闭包。 闭包的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。
  • 闭包的另一个用处,是封装对象的私有属性和私有方法。

8.数组

  • 数组属于一种特殊的对象

  • 数组长度length属性

    • length属性是可写的。如果人为设置一个小于当前成员个数的值,该数组的成员会自动减少到length设置的值。
    • 将数组清空的一个有效方法,就是将length属性设为0。
    • 如果人为设置length大于当前元素个数,则数组的成员数量会增加到这个值,新增的位置都是空位。
    • 在ECMAScript 5中,可以用Object.defineProperty() 让数组的length属性变成只读。
  • 空位

    • 当数组的某个位置是空元素,即两个逗号之间没有任何值,我们称该数组存在空位 var arr=【1,,2】
    • 但是,如果最后一个元素后面有逗号,并不会产生空位。数组直接量的语法允许有可选的结尾的逗号,故[,,]只有两个元素而非三个。
  • 类数组对象

    • 在JavaScript中,有些对象被称为“类数组对象”。意思是,它们看上去很像数组,可以使用length属性,但是它们并不是数组,无法使用一些数组的方法。

    • 由于类数组对象没有继承自Array.prototype,那就不能在它们上面直接调用数组方法。不过我们可以间接的使用Function.call方法调用。

六 . JavaScript错误处理机制

  • javascript解析或执行时,一旦发生错误,引擎就会自动抛出一个错误对象,js提供一个Error构造函数,所有抛出的错误都是这个构造函数的实例 var err=new Error(‘出错了’);err.message

  • Erroe对象的属性

    • message:错误提示信息
    • name:错误名称(非标准属性)
    • stack:错误的堆栈(非标准属性)
  • Error的六大派生对象

    • SyntaxError:是解析代码时发生的错误(变量名错误或者缺少括号)
    • ReferenceError:是引用一个不存在的变量时发生的的错误或者将一个值分配给无法分配的对象,比如对函数的运行结果或者this赋值(console.log()=1)
    • RangeError:是当一个值超过有效范围时发生的错误,主要有几种情况,一是数组长度为负数,二是Number对象的方法参数超出范围,以及函数堆栈超过最大值
      • new Array(-1)
      • (1234).toExponential(21)//toExponential() argument must be between 0 and 20
    • TypeError:是参数或变量不是预期类型时发生的错误。比如,对字符串,布尔值,数值等原始类型的值使用new命令,就会抛出这种错误,因为new命令的参数应该是一个构造函数 new 123
    • URIError:是URI相关函数的参数不正确时抛出的错误,主要涉及encodeURI(),decodeURI(),encodeURIComponent(),decodeURIComponent(),escape(),unescape()
    • EvalError:函数没有被正确执行时抛出EvalError错误,该错误类型已不再ES5中出现,只是为了与以前代码兼容
  • 自定义错误

    function UserError(message){

    this.message=message ||”默认信息”;

    this.name=”UserError”;}

    UserError.prototype=new Error();

    UserError.prototype.constructor=UserError;

  • throw语句:作用是中断程序执行,抛出一个意外或错误,他接受一个表达式作为参数,可以抛出各种值

七 . JavaScript JSON

  • JSON英文全称JavaScript Object Notation

  • 是一种易于理解的独立的语言,也是一种轻量级的数据交换格式

  • JSON使用JavaScript语法,但是JSON格式仅仅是一个文本。文本可以被任何编程语言读取及作为数据传递格式

  • 语法规则

    • 数据以键值对形式出现
    • 数据由逗号分隔
    • 大括号保存对象
    • 方括号保存数组
  • 通常我们从服务器中读取JSON数据,并在网页中显示数据

  • JSON字符串转换为js对象

    • 创建js字符串,字符串为JSON格式的数据

      var text = ‘{ “employees” : [‘ +
      ‘{ “firstName”:”John” , “lastName”:”Doe” },’ +
      ‘{ “firstName”:”Anna” , “lastName”:”Smith” },’ +
      ‘{ “firstName”:”Peter” , “lastName”:”Jones” } ]}’;

    • 然后使用js内置函数JSON.parse()将字符串转化为js对象

    • var obj=JSON.parse(text);

    • 最后在你的页面使用js对象

八 . JavaScript:void(0)的含义

  • void关键字是js中非常重要的关键字,该操作符指定要计算一个表达式但是不返回值

    点我!

  • href=”#”与href=”javascript:void(0)”的区别

    # 包含了一个位置信息,默认的锚是#top 也就是网页的上端。

    而javascript:void(0), 仅仅表示一个死链接。

    在页面很长的时候会使用 # 来定位页面的具体位置,格式为:# + id

    如果你要定义一个死链接请使用 javascript:void(0) 。

  • void()仅仅是代表不返回任何值,但是括号内的表达式还是要运行

九 . 命名规范

  • 变量名应该区分大小写,允许包含字母、数字、美元符号($)和下划线,但第一个字符不允许是数字,不允许包含空格和其他标点符号;

  • 变量命名长度应该尽可能的短,并抓住要点,尽量在变量名中体现出值的类型;

  • 变量名的命名应该是有意义的;

  • 变量名不能为JavaScript中的关键词、保留字全名;

  • 变量名命名方法常见的有匈牙利命名法、驼峰命名法和帕斯卡命名法。

  • 空格与运算符

    通常运算符 ( = + - * / ) 前后需要添加空格:

  • 代码缩进

    通常使用 4 个空格符号来缩进代码块:

    注意:不推荐使用 TAB 键来缩进,因为不同编辑器 TAB 键的解析不一样。

  • 复杂语句的通用规则:

    • 一条语句通常以分号作为结束符。
    • 将左花括号放在第一行的结尾。
    • 左花括号前添加一空格。
    • 将右花括号独立放在一行。
    • 不要以分号结束一个复杂的声明。
  • 对象定义的规则:

    • 将左花括号与类名放在同一行。
    • 冒号与属性值间有个空格。
    • 字符串使用双引号,数字不需要。
    • 最后一个属性-值对后面不要添加逗号。
    • 将右花括号独立放在一行,并以分号作为结束符号。
  • 命名规则
    • 变量和函数为驼峰法( camelCase
    • 全局变量为大写 (UPPERCASE )
    • 常量 (如 PI) 为大写 (UPPERCASE )

十.文档对象模型HTML DOM

DOM HTML tree

  • 通过可编程的对象模型,js能够改变页面中的所有HTML元素,属性,CSS样式,能对页面中的所有事件作出反应

1.找HTML元素

  • 通过id document.getElementById(“id值”);
  • 通过标签名 document.getElementByTagName(“标签名”);
  • 通过类名 document.getElementByClassName(“类名”);

2.节点指针

  • firstChild :获取元素的首个子节点
  • lastChild :获取元素的最后一个子节点
  • 父节点.childNodes :获取元素的子节点列表
  • 兄弟节点.previousSibling:获取已知节点的前一个节点
  • 兄弟节点.nextSibling : 获取已知节点的后一个节点
  • 子节点.parentNode :获取已知节点的父节点

3.创建节点

  • 创建元素节点 document.createElement(元素标签)
  • 创建属性节点 document.createAttribute(元素属性)
  • 创建文本节点 document.createTextNode(文本内容)

4.插入节点

  • 向节点的子节点列表的末尾添加新的子节点 appendChild(所添加的新节点)
  • 在已知的子节点前插入一个新的子节点 insertBefore(所要添加的新节点,已知节点)

img

5.改变HTML元素样式

document.getElementById(id).style.property=new style;

6.添加监听事件

element.addEventListener(event,function,useCapture);

第一个参数就是事件的类型(如“click”或“mousedown”。注意不要使用“on”前缀,是“click”而非“onclick”)

第二个参数就是事件触发时调用的函数

第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的

7.事件冒泡或事件捕获?

事件传递有两种方式:冒泡与捕获。

事件传递定义了元素事件触发的顺序。 如果你将

元素插入到

元素中,用户点击

元素, 哪个元素的 “click” 事件先被触发呢?

在冒泡中,内部元素的事件会先被触发,然后再触发外部元素,即:

元素的点击事件先触发,然后会触发

元素的点击事件。

在捕获中,外部元素的事件会先被触发

img

刷题笔记

html

  1. form表单中input元素的disabled指当input元素加载时禁用此元素,input内容不会随着表单提交。readonly规定输入字段为只读,input内容会随着表单提交。但是无论设置readonly还是disabled,通过js脚本都能更改input的value。

  2. <parent><child>content</child></parent>可使child内容垂直居中。

    1
    2
    3
    4
    5
    6
    7
    8
    /*把parent变成table,child变成table-cell,而vertical-align可设置元素垂直对齐,前提是:只能应用于内联元素,当parent只有child一个子元素时,child会铺满parent全部空间,即使child有宽高*/
    parent{
    display:table;
    }
    child{
    display:table-cell;
    vertical-align: middle;
    }
    1
    2
    3
    4
    5
    /*弹性布局。*/
    parent{
    display:flex;
    align-items:center;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    /*父元素设置相对定位,子元素设置绝对定位,子元素的top设置50%,即父元素的高度一半,注意此时是child元素的左上角(0,0)移到了parent的(0,parent高度的50%),而不是子元素的中心点移到了父元素垂直方向的中心点。因此子元素需要上移自身高度的一半,即transform:translateY(-50%)*/
    parent{
    positionn: relative;
    }
    child{
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /*设置伪元素。vertical-align属性定义行内元素的基线相对于该元素所在行的基线的垂直对齐。如:有两个行内元素a和b,a,b都是img,若s加了vertical-align:middle样式,b的底部(基线)就会对齐a的中间位置;若a,b都加了,则互相对齐了对方的中间位置,也就是他们在垂直方向上的中线对齐了。*/
    parent::after{
    content:'';
    height: 100%;
    vertical-align: middle;
    width:0;
    }
    child{
    display: inline-block;
    vertical-align: middle;
  3. display:none指的是元素不完全陈列出来,不占据空间,涉及到了DOM结构,故产生重排和重绘。

    visibility:hidden指的是元素不可见但存在,保留空间,不影响结构,故只产生重绘,但不可触发绑定事件。

    opacity=0指的是元素不可见但存在,保留空间,不影响结构,并且如果如果该元素已经绑定了一些事件,如click事件,那么点击该区域,也能触发点击事件的。

  4. Web SQL数据库API并不是HTML5规范的一部分,但它是一个独立的规范,引入了一组使用SQL操作数据库的APIs。

  5. 1
    2
    3
    4
    ele.clientWidth = 宽度 + padding
    ele.offsetWidth = 宽度 + padding + border
    ele.scrollTop = 被卷去的上侧距离
    ele.scrollHeight = 自身实际的高度(不包含边框)
  6. Object.keys()不能遍历出对象原型链上的属性。Object.assign(obj1,obj2)可以实现对象的浅拷贝。

  7. null === null结果为true。

  8. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class A{}
    class B extends A{}
    const a = new A();
    const b = new B();

    //以下都为true
    a.__proto__ === A.prototype
    b.__proto__ === B.prototype
    B.__proto__ === A
    B.prototype.__proto__ === A.prototype
    b.__proto__.__proto__ === A.prototype

前端cookie解读

补充:当关闭浏览器或关机后重新打开,存放在硬盘上的数据不会消失,而存放在内存中的数据会消失。

Cookie的引入

当用户在未登录状态下在京东购物网站向购物车中添加某些商品后将浏览器关闭,然后再打开浏览器访问京东,此时查看购物车会发现,购物车中仍然有刚才添加的商品,这其实就是cookie的功劳。

Cookie是一段不超过4KB的小型文本数据,由一个名称name,一个值value和其他几个控制Cookie有效期,安全性,使用范围的可选属性组成。

  1. name/value:设置Cookie的名称及相应的值,对于认证的Cookie,value值包括Web服务器所提供的访问令牌。
  2. expires属性:设置Cookie的生命周期。有两种存储类型的Cookie:会话性和持久性。Expires属性缺省时,为会话性Cookie,仅保留在客户端内存中,并在用户关闭浏览器时失效;持久性Cookie会保存在用户的硬盘中,直至生存期或用户直接在网页中单击注销等按钮结束会话时才会失效。
  3. path属性:定义了Web站点上可以访问该Cookie的目录。
  4. Domain属性:指定了可以访问该Cookie的Web站点或域。Cookie机制并未遵循严格的同源策略,允许一个子域可以设置或获取其父域的Cookie。当需要实现单点登陆方案时,Cookie的上述特性非常有用,然而也增加了Cookie受攻击的危险,比如攻击者可以借此发动会话定置攻击。因而,浏览器禁止在Domain属性上设置.org、.com等顶级域名,以及在国家级及地区顶级域下注册的二级域名,以减少攻击的范围。
  5. Secure属性:指定是否使用HTTPS安全协议发送Cookie。使用HTTPS安全协议,可以保护Cookie在浏览器和Web服务器间的传输过程中不被窃取和篡改。该方法也可用于Web站点的身份鉴别,即在HTTPS的连接建立阶段,浏览器会检查Web网站的SSL证书的有效性。但是基于兼容性的原因(比如有些网站使用自签署的证书)在检测到SSL证书无效时,浏览器并不会立即终止用户的连接请求,而是显示安全风险信息,用户仍可以选择继续访问该站点。由于许多用户缺乏安全意识,因而仍可能连接到Pharming攻击所伪造的网站。
  6. HTTPOnly 属性 :用于防止客户端脚本通过document.cookie属性访问Cookie,有助于保护Cookie不被跨站脚本攻击窃取或篡改。但是,HTTPOnly的应用仍存在局限性,一些浏览器可以阻止客户端脚本对Cookie的读操作,但允许写操作;此外大多数浏览器仍允许通过XMLHTTP对象读取HTTP响应中的Set-Cookie头
Cookie的简介

cookie是属于web开发的技术,由若干键值对构成,且键值对均为字符串。它是所有web开发语言据支持的技术。它是一种进行网络会话状态跟踪的技术。

会话(当用户打开浏览器,从发出第一次请求开始,一直到最终关闭浏览器就表示一次会话的完成)则是由一组请求和响应组成,是围绕看一件相关事情所进行的请求和响应,所以这些请求和响应之间必须有数据传递,即进行会话状态跟踪。但http协议是一种无状态协议,在不同请求间无法进行数据传递。此时就需要一种可以进行请求间数据传递的会话跟踪技术,而cookie就是这样一种技术。

Cookie是由服务器生成,保存在客户端的一种信息载体。这个载体中存放着用户访问该站点的会话状态信息。只要cookie没有被清空,或cookie没有生效,那么保存在其中的会话状态就有效。用户在提交第一次请求后,由服务器生成cookie并将其封装到响应头中,以响应的形式发送给客户端,客户端接收到这个响应后,将cookie保存到客户端。当客户端再发起同类的请求(资源路径路径相同)后,在请求中会携带保存在客户端的cookie数据,发送给服务器,由服务器对会话进行跟踪。

注意:cookie禁用仅是客户端不接收来自客户端的cookie,后端服务器还是有响应cookie回来的。一般不会禁用cookie,否则就不能使用,会出现500错误。

cookie是什么

简单讲,cookie就是浏览器存储在用户电脑上的一小段文本文件。cookie是纯文本格式,不包含任何可执行的代码。一个web页面或者服务器告知浏览器按照一定规则来存储这些信息,并在随后的请求中将这些信息发送至服务器,web服务器就可以使用这些信息来识别不同的用户。大多数需要登陆的网站在用户验证之后都会设置一个cookie,只要这个cookie存在并可使用,用户就可以自由浏览这个网站的任意页面。再次说明,cookie只包含数据,就其本身而言并不有害。

设置Cookie的失效时间:

如果Cookie没有设置expires属性,那么 cookie 的生命周期只是在当前的会话中,

关闭浏览器意味着这次会话的结束,此时 cookie 随之失效。

1、当设置的失效时间大于等于1天时,我们可以在 expires 属性后面直接输入XX天数

1
2
3
4
5
6
Cookies.set('name', 'value', {
expires: 7,
});
// => 'value'
Cookies.get('name');
Cookies.remove('name');

2、当设置的失效时间少于一天时:我们需要在当前的时间上加上失效时间。

例如下面是设置cookie的失效时间为15分钟。

1
2
3
4
5
6
7
var millisecond = new Date().getTime();
var expiresTime = new Date(millisecond + 60 * 1000 * 15);

Cookies.set('name', 'value', {
expires: expiresTime,

});

PS:如果expires设置一个过去的时间点,那么这个cookie 会被立即删掉(失效)。

Session

session即会话,是web开发中的一种会话状态跟踪技术,跟cookie类似,不过cookie是将会话状态存放于客户端的,而session是存在于服务端的。

服务端生成session

在服务器中系统会为每个会话维护一个session。不同的会话,对应不同的session。服务器对当前应用中的session是以Map的形式进行管理的,这个Map称为Session列表,该map的key为一个32位长度的随机串,这个随机串称为JSession,value则为session对象的引用。当用户第一次提交请求时,服务端servlet中执行到request.getSession()后会自动生成一个Map.Entry对象,key为一个根据某种算法新生成的JSessionID,value则为新创建的HttpSession对象。

服务器生成并发送cookie

在将Session信息写入session列表后,系统还会自动将JSESSIONID作为name,这个32位长度的随机串作为value,以cookie的形式存放到响应头中,并随着响应将该cookie发送到客户端。

客户端接收并发送cookie

客户端接受到这个cookie后会将其存放到浏览器的缓存中。即只要客户端浏览器不关闭,浏览器缓存的cookie就不会消失。

当用户提交第二次请求时,会将缓存中的这个cookie伴随着请求的头部信息一块发到服务端。

congsession列表中查找

服务端从请求中读取到从客户端发来的cookie,并根据cookie的JSESSIONID的值,从Map中查找相应key所对应的value,即session对象。然后对该session对象的域属性进行读写操作。

session的失效

web开发中引入的session超时的概念,session的失效就是指session的超时。若某个session在指定的时间范围内一直未被访问,那session将超时,即将失效。

服务器针对不同的会话找到不同的session,是因为cookie完成了会话的跟踪。但是,若客户端浏览器将cookie禁用,则服务器每提交一次请求,服务器在给出的响应中都会包含名称为JSESSIONID的cookie,只不过这个cookie值每次都不同,也就是说客户端所提交的请求中没有包含JSESSIONID,服务器就会认为这是一次新的会话的开始,就会为其生成一个Map.Entry对象,所以也就无法实现会话跟踪了。

安全威胁

https://baike.baidu.com/item/cookie/1119#reference-[3]-5062332-wrap

前端经验

字体图标的使用

字体图标的优势
  1. 性能好,可以减少http请求。
  2. 解决图标放大失真问题。
  3. 解决图片占用内存问题。
图片格式分类
  1. 位图图片:bmp,jpg,gif,png。(大小改变时可能出现锯齿状)。
  2. 矢量图图片:以svg格式为代表,可缩放矢量图形(Scalable Vector Graphics)。SVG是一种使用XML格式定义的图像。(颜色和字体可选范围较小)
字体图标出现的背景

雪碧图处理图标

  • 首先载入带有所有图标的图片。
  • 利用定位截取想要的图标。
1
2
3
4
5
6
7
8
9
10
11
12
.bgImg{
background: url(img/logos.png);
display: block;
text-indent: -9999px;
overflow: hidden;
background-repeate: no-repeate;
width: 16px;
height: 16px;
}
.help{
background-position: -48px -150px;
}

优势:当有大量的小图标时,可减少请求次数,网页加载速度更快,减少阻塞网络的情况,用户体验不好。

缺点:需要先设置背景图片,再通过精灵图中小图标的宽度和位置,设置对应的div宽高和背景定位坐标。设计人员后期的维护难度较大,编码也比较难(对定位精准性要求较大)。

字体图标的使用
  • 一般会再建一个新的css文件来设置font-family和字体颜色,一来可以整体设置,二来当新字体图标覆盖时,文字的样式可以保持原先的状态。

星级评分

linux学习

linux基础

linux实战

远程登陆

xShell xFtp

实用指令
远程管理
vi和vim编译器
定时任务调度
RPM与YUM

pandas之excel

pandas

创建文件
1
2
3
4
5
import pandas as pd
df = pd.DataFrame({'ID':[1,2,3],'Name':['Tim','Victor','Nick']})
df = df.set_index('ID')
df.to_excel('F:/webProject/python/output.xlsx')
print('Done')

遇到问题:

  1. NameError: name ‘pandas’ is not defined?

    这是没有pandas模块,这是因为python默认没有安装numpy和pandas,最直接的方法是在python的scripts中执行pip install pandas不过,据说用pip安装会损坏原文件。

  2. 或者在Spyder编辑器中安装pip install pandas,却报Note: you may need to restart the kernel to use updated packages.?

    在Terminal中更新conda update spyder

打开文件
1
2
3
4
5
6
7
8
9
10
import pandas as pd 
people = pd.read_execl('path',header=None) #表示没有行头
people.set_index('ID',inplace=True)
print(people.shape) #打印出多少行多少列
print(people.columns) #列
print(people.head(3)) #打印出前3行,head不加参数默认为5行
print(people.tail(3))

df = pd.read_excel('path',index_col='ID') #后面的参数是为了不要将系统自动添加的索引加到新的表中
df.to_excel('path')
|