js从入门到精通到深入到就业

本篇博客是我参看人家代码做的总结,个人感觉非常非常好,简单、步步深入,不用花大量时间来学完正本js,只需要把其中的代码理解透彻,上班无压力(上班无压力是指js部分,包括查看框架源代码都有很大帮助)

///////////////////////////dom/////////////

------通过Id、name、TagName..获得节点

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

function getPwd() {

//DOM中的第一个常用的方法是getElementById-->表示通过id来获取某个特定的标签,获取的是一个值

var pwd = document.getElementById("pwd");

// alert(pwd.value);

var pc = document.getElementById("showPwd");

pc.innerHTML = pwd.value;

}

function getUsers() {

//根据标签的name属性来获取一组标签对象,这个方法一般都只用于表单的获取

var users = document.getElementsByName("users");

for(var i=0;i<users.length;i++) {

alert(users[i].value);

}

}

function getInputs() {

//根据标签的名称获取一组元素,这个非常的有用,一般用于获取html的各种标签,以此完成各种操作

//一共能够获取页面的10个元素

var is = document.getElementsByTagName("input");

for(var i=0;i<is.length;i++) {

alert(is[i].value);

}

}

</script>

</head>

<body>

<input type="text" name="users" />

<input type="text" name="users" />

<input type="text" name="users" />

<input type="text" name="users" />

<input type="text" name="users" />

<input type="text" name="users" />

<br/>

<input type="password" />

<br/>

<input type="button" value="获取users" onclick="getUsers()"/>

<input type="button" value="获取PWD" onclick="getPwd()"/>

<input type="button" value="获取Input" onclick="getInputs()"/>

<br/>

<div >

<h1>dddd</h1>

</div>

</body>

</html>

--------------------节点名、节点值、节点类型以及根据节点关系获取邻居节点、父子节点..

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

function getAllH1() {

var ah = document.getElementsByTagName("h1");

for(var i=0;i<ah.length;i++) {

// //获取节点中的文本内容

// alert(ah[i].innerHTML);

// //获取节点的名称

// alert(ah[i].nodeName);

// //获取节点的类型

// alert(ah[i].nodeType);

// //获取节点中的值:节点中的值只是在针对文本节点时有用

// alert(ah[i].nodeValue);

// //获取某个节点的文本节点

// alert(ah[i].firstChild.nodeType);

//获取某个文本节点的值,对于IE和firefox而言文本的空格不一致,对于IE而言,仅仅只会把换行加入空白,但是FF而言就是全部空格

//所以在获取文本节点值的时候,需要把空格去除

alert("|"+ah[i].firstChild.nodeValue+"|");

}

}

function getConH2() {

var con = document.getElementById("content");

var h2 = con.getElementsByTagName("h2");

//得到的h2元素是一个数组

alert(h2[0].innerHTML);

//通过h2这个节点来找到h3中span的值

//1、找到父节点

var pn = h2[0].parentNode;

//2、通过父节点找到名称为h3的节点

var h3 = pn.getElementsByTagName("h3")[0];

//3、通过h3找到span

var s = h3.getElementsByTagName("span")[0];

alert(s.innerHTML);

}

</script>

</head>

<body>

<div >

<h1>

aaaaa1

<span>aaaaassss</span>

</h1>

<h2>

bbbbbbbbb1

<span>bbbbbssss</span>

</h2>

<h3>

cccccccc1

<span>ccccccssss</span>

</h3>

</div>

<h1>

hhhhhhhaaaaa1

<span>hhhhhhhhhhhaaaaassss</span>

</h1>

<h2>

hhhhhhhhhhbbbbbbbbb1

<span>hhhhhhbbbbbssss</span>

</h2>

<h3>

hhhhhhhhhhhcccccccc1

<span>hhhhhhhhhhhhhccccccssss</span>

</h3>

<input type="button" value="获取所有的h1" onclick="getAllH1()" />

<input type="button" value="获取content的h2" onclick="getConH2()" />

</body>

</html>

////////////////////////////////////////事件函数//////////////////

------对不同浏览器事件对象的兼容处理

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

</script>

</head>

<body>

<ul>

<li>aaaaaaaaaaaaaa</li>

<li>bbbbbbbbbbbbbb</li>

<li>cccccccccccccc</li>

<li>dddddddddddddd</li>

<li>eeeeeeeeeeeeee</li>

</ul>

<input type="button" value="点击一下" />

<script type="text/javascript">

var btn = document.getElementById("btn");

//可以通过如下方式来绑定事件,这样绑定事件,就可以完成事件和html的解耦合操作

//在开发中通常都是使用这种方式来绑定事件

//这个事件的处理函数中默认有一个event的参数,用来获取相应的事件信息

btn.onclick = function(event) {

//特别注意:对于IE而言,不会自动传递event这个参数进去,IE需要通过window.event来获取事件

//但是FF却不支持window.event,所以通常使用如下方式解决

event = event||window.event;

alert(event.type);

//this就表示这个按钮对象

alert(this.value);

}

</script>

</body>

</html>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

//当窗口加载完毕之后才执行init方法,这样可以省略body中的onload

//所以如果希望使用如下的事件定义方式,需要先完成html信息的加载

window.onload = init;

/**

* 此时init方法是在body的onload之后执行,就等于在所有的页面标签加载完毕之后才执行init,此时节点就存在了

*/

function init() {

alert("abc");

var btn = document.getElementById("btn");

/**

* 如下绑定方式带来最大的一个问题是如果将该段代码放到head中定义,在执行到绑定事件的时候并没有把html的标签

* 渲染出来,所以通过DOM得到的节点都是null的,就报错了,解决这个问题的方法是在页面加载完成之后才调用以下这段代码

* 可以在body中的通过onload事件来处理

*/

btn.onclick = function(event) {

//特别注意:对于IE而言,不会自动传递event这个参数进去,IE需要通过window.event来获取事件

//但是FF却不支持window.event,所以通常使用如下方式解决

event = event||window.event;

alert(event.type);

//this就表示这个按钮对象

alert(this.value);

}

}

</script>

</head>

<body>

<ul>

<li>aaaaaaaaaaaaaa</li>

<li>bbbbbbbbbbbbbb</li>

<li>cccccccccccccc</li>

<li>dddddddddddddd</li>

<li>eeeeeeeeeeeeee</li>

</ul>

<input type="button" value="点击一下" />

</body>

</html>

-------------

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

//当窗口加载完毕之后才执行init方法,这样可以省略body中的onload

//所以如果希望使用如下的事件定义方式,需要先完成html信息的加载

window.onload = init;

/**

* 此时init方法是在body的onload之后执行,就等于在所有的页面标签加载完毕之后才执行init,此时节点就存在了

*/

function init() {

alert("abc");

var btn = document.getElementById("btn");

/**

* 如下绑定方式带来最大的一个问题是如果将该段代码放到head中定义,在执行到绑定事件的时候并没有把html的标签

* 渲染出来,所以通过DOM得到的节点都是null的,就报错了,解决这个问题的方法是在页面加载完成之后才调用以下这段代码

* 可以在body中的通过onload事件来处理

*/

btn.onclick = function(event) {

//特别注意:对于IE而言,不会自动传递event这个参数进去,IE需要通过window.event来获取事件

//但是FF却不支持window.event,所以通常使用如下方式解决

event = event||window.event;

alert(event.type);

//this就表示这个按钮对象

alert(this.value);

}

}

</script>

</head>

<body>

<ul>

<li>aaaaaaaaaaaaaa</li>

<li>bbbbbbbbbbbbbb</li>

<li>cccccccccccccc</li>

<li>dddddddddddddd</li>

<li>eeeeeeeeeeeeee</li>

</ul>

<input type="button" value="点击一下" />

</body>

</html>

--------------------------------页面加载完成后执行函数

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

//当窗口加载完毕之后才执行init方法,这样可以省略body中的onload

//所以如果希望使用如下的事件定义方式,需要先完成html信息的加载

window.onload = init;

/**

* 此时init方法是在body的onload之后执行,就等于在所有的页面标签加载完毕之后才执行init,此时节点就存在了

*/

function init() {

//1、找到所有的li

var lis = document.getElementsByTagName("li");

//2、为所有的li绑定事件

for(var i=0;i<lis.length;i++) {

lis[i].onmouseover = changeColor;

lis[i].onmouseout = reColor;

}

}

function changeColor() {

this.style.color = "#f00";

}

function reColor() {

this.style.color = "#000";

}

</script>

</head>

<body>

<ul>

<li>aaaaaaaaaaaaaa</li>

<li>bbbbbbbbbbbbbb</li>

<li>cccccccccccccc</li>

<li>dddddddddddddd</li>

<li>eeeeeeeeeeeeee</li>

</ul>

<input type="button" value="点击一下" />

</body>

</html>

//////////////////////////////////////////函数-对象之间的关系//////////

-------------函数内存的拷贝、函数是一个特殊的对象

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

//第一种定义方式

function fn1() {

alert("fn1");

}

//函数就是一个非常特殊的对象,是一个Function类的实例,其实在内存中存储的操作是通过一个键值对来存储的

alert(typeof fn1);

//由于函数是一个对象,所以可以通过如下方式定义

//以下是通过函数的拷贝来完成赋值,两个引用并没有指向同一个对象

var fn2 = fn1;

fn2();

fn1 = function() {

alert("fnn1");

}

/**

* 函数虽然是一个对象,但是却和对象有一些区别,对象是通过引用的指向完成对象的赋值的,而函数却是通过对象的拷贝来完成的

* 所以fn1虽然变了,并不会影响fn2

*/

fn2();

fn1();

/**

* 对于对象而言,是通过引用的指向来完成赋值的,此时修改o1或者o2会将两个值都完成修改

*/

var o1 = new Object();

var o2 = o1;

o2.name = "Leon";

alert(o1.name);

</script>

</head>

<body>

</body>

</html>

--------------------------对象内存的引用

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

// function sum(num1,num2) {

// return num1+num2;

// }

var sum = function(num1,num2) {

return num1+num2;

}

// function sum(num1) {

// return num1+100;

// }

/**

* 此时sum所指向的空间已经从有两个参数的函数变化到只有num1的函数中

* 在调用的时候就只会调用只有num1的函数

* 特别指出:函数的参数和调用没有关系,如果函数只有一个参数,但是却传入

* 了两个参数,仅仅只会匹配一个

* 所以在js中函数不存在重载

*/

var sum = function(num1) {

return num1+100;

}

//函数有如下一种定义方式

/**

* 如下定义方式等于定义了一个

* function fn(num1,num2){

* alert(num1+num2);

* }

* 所以通过以下的例子,充分的说明函数就是一个对象

*/

var fn = new Function("num1","num2","alert(\'fun:\'+(num1+num2))");

fn(12,22);

alert(sum(19));

alert(sum(19,20));

</script>

</head>

<body>

</body>

</html>

-------就是、核心中的核心、函数作为参数传递以及函数作为返回值

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

/**

* 由于函数是对象,所以可以直接把函数通过参数传递进来

*/

function callFun(fun,arg) {

//第一个参数就是函数对象

return fun(arg);

}

function sum(num) {

return num+100;

}

function say(str) {

alert("hello "+str);

}

//var say = xxx

//调用了say函数

callFun(say,"Leon");

//调用了sum函数

alert(callFun(sum,20));

function fn1(arg) {

/**

* 此时返回的是一个函数对象

*/

var rel = function(num) {

return arg+num;

}

return rel;

}

//此时f是一个函数对象,可以完成调用

var f = fn1(20);

alert(f(20));

alert(f(11));

</script>

</head>

<body>

</body>

</html>

-------------------------------返回函数的具体实列,我朋友公司用到过这类需求,当时还没解决。。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

</head>

<body>

<div ></div>

<script type="text/javascript">

/**

* 根据数字来进行排序的函数

*/

// function sortByNum(a,b) {

// return parseInt(a)-parseInt(b);

// }

// alert("11"+1);

// //当进行减法的时候,会自动完成转换

// alert("11"-1);

// var as = [1,2,"11px",33,"12px",190];

// //对于js而言,默认是按照字符串来进行排序的

// as.sort(sortByNum);

// alert(as);

//测试根据对象排序

function Person(name,age) {

this.name = name;

this.age = age;

}

var p1 = new Person("Leno",39);

var p2 = new Person("John",23);

var p3 = new Person("Ada",41);

var ps = [p1,p2,p3];

// ps.sort(sortByAge);

//p1.name,p1["name"]

/**

* 使用以下方法来处理排序,带来的问题是需要为每一个属性都设置一个函数,显然不灵活

* 但是如果通过函数的返回值调用就不一样了

*/

// function sortByName(obj1,obj2) {

// if(obj1.name>obj2.name) return 1;

// else if(obj1.name==obj2.name) return 0;

// else return -1;

// }

// function sortByAge(obj1,obj2) {

// return obj1.age-obj2.age;

// }

//

ps.sort(sortByProperty("age"))

function sortByProperty(propertyName) {

var sortFun = function(obj1,obj2) {

if(obj1[propertyName]>obj2[propertyName]) return 1;

else if(obj1[propertyName]==obj2[propertyName])return 0;

else return -1;

}

return sortFun;

}

function show() {

var p = document.getElementById("person");

for(var i=0;i<ps.length;i++) {

p.innerHTML+=ps[i].name+","+ps[i].age+"<br/>";

}

}

show();

</script>

</body>

</html>

/*===================length属性====================*/

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

</head>

<body>

<div ></div>

<script type="text/javascript">

function sum(num1,num2) {

return num1+num2;

}

function callSum1(num1,num2) {

//使用sum这个函数来完成一次调用,调用的参数就是callSum1这个函数的参数

//apply的第二个参数表示一组参数数组

return sum.apply(this,arguments);

}

function callSum2(num1,num2) {

//关键就是第二个参数是数组

return sum.apply(this,[num1,num2]);

}

alert(callSum1(12,22));

alert(callSum2(22,32));

function callSum3(num1,num2) {

//call是通过参数列表来完成传递,其他和apply没有任何区别

return sum.call(this,num1,num2);

}

alert(callSum3(22,33));

</script>

</body>

</html>

/*==========call===========*/

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

</head>

<body>

<div ></div>

<script type="text/javascript">

/**

* 当需要创建一个类的时候,设置类的属性和方法需要通过this关键字来引用

* 但是特别注意:this关键字在调用时会根据不同的调用对象变得不同

*/

var color = "red";

function showColor() {

alert(this.color);

}

/**

* 创建了一个类,有一个color的属性和一个show的方法

*/

function Circle(color) {

this.color = color;

}

var c = new Circle("yellow");

showColor.call(this);//使用上下文来调用showColor,结果是red

showColor.call(c);//上下文对象是c,结果就是yellow

/**

* 通过以上发现,使用call和apply之后,对象中可以不需要定义方法了

* 这就是call和apply的一种运用

*/

</script>

</body>

</html>

/*================js创建对象==============*/

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

/**

* 在js中并不存在类,所以可以直接通过Object来创建对象

* 但是使用如下方式创建,带来最大的问题是,由于没有类的约束

* 无法实现对象的重复利用,并且没有一种约定,在操作时会带来问题

*/

var person = new Object();

person.name = "Leon";

person.age = 33;

person.say = function() {

alert(this.name+","+this.age);

}

</script>

</head>

<body>

</body>

</html>

/*==============json对象==================*/

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

/**

* json的意思就是javascript simple object notation

* json就是js的对象,但是它省去了xml中标签,而是通过{}来完成对象的说明

*/

var person = {

name:"张三",//通过属性名:属性值来表示,不同的属性通过,来间隔

age:23,

say:function() {

alert(this.name+","+this.age);

}//最后一个属性之后不能有,

}

person.say();

/**

* 通过json依然可以创建对象数组,创建的方式和js的数组一样

*/

var ps = [

{name:"Leon",age:22},

{name:"Ada",age:33}

];

for(var i=0;i<ps.length;i++) {

alert(ps[i].name);

}

/**

* 创建一组用户,用户的属性有

* name:string,age:int,friends:array

* List<Person> ps = new ArrayList<Person>();

* ps.add(new Person("Leon",22,["Ada","Alice"]));

* ps.add(new Person("John",33,["Ada","Chris"]));

* 把ps转换为json

*/

ps = [

{

name:"Leon",

age:22,

friends:["Ada","Alice"]

},

{

name:"John",

age:33,

friends:["Ada","Chris"]

}

];

</script>

</head>

<body>

</body>

</html>

/*======工厂方式创建对象===========*/

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

/**

* 通过工厂的方式来创建Person对象

* 在createPerson中创建一个对象

* 然后为这个对象设置相应的属性和方法

* 之后返回这个对象

*/

function createPerson(name,age) {

var o = new Object();

o.name = name;

o.age = age;

o.say = function() {

alert(this.name+","+this.age);

}

return o;

}

/**

* 使用工厂的方式,虽然有效的解决了类的问题,但是依然存在另外一个问题

* 我们无法检测对象p1和p2的数据类型

*/

var p1 = createPerson("Leon",22);

var p2 = createPerson("Ada",33);

p1.say();

p2.say();

</script>

</head>

<body>

</body>

</html>

/*========构造函数创建对象并优化==========*/

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

/**

* 通过构造函数的方式创建,和基于工厂的创建类似

* 最大的区别就是函数的名称就是类的名称,按照java的约定,第一个

* 字母大写。使用构造函数创建时,在函数内部是通过this关键字来

* 完成属性的定义

*/

function Person(name,age) {

this.name = name;

this.age = age;

//以下方式带来的问题是所有的对象都会为该行为分配空间

// this.say = function() {

// alert(this.name+","+this.age);

// }

this.say = say;

}

/**

* 将行为设置为全局的行为,如果将所有的方法都设计为全局函数的时候

* 这个函数就可以被window调用,此时就破坏对象的封装性

* 而且如果某个对象有大 量的方法,就会导致整个代码中充斥着大量的全局函数

* 这样将不利于开发

*/

function say() {

alert(this.name+","+this.age);

}

/*

* 通过new Person来创建对象

*/

var p1 = new Person("Leon",22);

var p2 = new Person("Ada",32);

p1.say(); p2.say();

/**

* 使用构造函数的方式可以通过以下方式来检测

* 对象的类型

*/

alert(p1 instanceof Person);

/**

* 使用构造函数创建所带来的第一个问题就是每一个对象中

* 都会存在一个方法的拷贝,如果对象的行为很多的话

* 空间的占用率就会大大增加

* 可以将函数放到全局变量中定义,这样可以让类中的行为指向

* 同一个函数

*/

alert(p1.say==p2.say);

</script>

</head>

<body>

</body>

</html>

/*==========原型对象非常非常重要==============*/

--------------1.原型创建对象

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

/**

* 以下演示了通过原型的创建方式,使用基于原型的创建可以将属性和方法

* 设置为Person专有的,不能再通过window来调用

*/

function Person(){

}

Person.prototype.name = "Leon";

Person.prototype.age = 23;

Person.prototype.say = function() {

alert(this.name+","+this.age);

}

var p1 = new Person();

p1.say();

//通过window没有办法调用say方法,如此就完成了封装

// say();

</script>

</head>

<body>

</body>

</html>

--------------------2原型内存分析

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

/**

* 原型是js中非常特殊一个对象,当一个函数创建之后,会随之就产生一个原型对象

* 当通过这个函数的构造函数创建了一个具体的对象之后,在这个具体的对象中

* 就会有一个属性指向原型

*/

//第一种状态

function Person(){

}

//第二种状态

Person.prototype.name = "Leon";

Person.prototype.age = 23;

Person.prototype.say = function() {

alert(this.name+","+this.age);

}

//第三中状态,创建了一个对象之后会有一个_prop_的属性指向原型

//在使用时如果在对象内部没有找到属性会去原型中找,_prop_属性是隐藏的

var p1 = new Person();

//p1.say();

//以下方法可以检测出p1是否有_prop_指向Person的原型

//alert(Person.prototype.isPrototypeOf(p1));

//第四种状态

var p2 = new Person();

//是在自己的空间中定义了一个属性,不会替换原型中的属性

p2.name = "Ada";

//p2.say();

//p1.say();

// //检测某个对象是否是某个函数的原型

// alert(Person.prototype.isPrototypeOf(p2));

// //检测某个对象的constructor

// alert(p1.constructor==Person);

// //检测某个属性是否是自己的属性

// alert(p1.hasOwnProperty("name"));//false,p1自己的空间中没有值

// alert(p2.hasOwnProperty("name"));//true,p2在自己的空间中设置了name属性

//delete p2.name;

//p2.say();

//alert(p2.hasOwnProperty("name"));//由于已经删除了,所以是false

//检测某个对象在原型或者自己中是否包含有某个属性,通过in检测

//alert("name" in p1);//true

//alert("name" in p2);//true

//alert("address" in p1);//在原型和自己的空间中都没有,false

alert(hasPrototypeProperty(p1,"name"));//true

alert(hasPrototypeProperty(p2,"name"));//false

/**

* 可以通过如下方法检测某个属性是否在原型中存在

*/

function hasPrototypeProperty(obj,prop) {

return ((!obj.hasOwnProperty(prop))&&(prop in obj))

}

</script>

</head>

<body>

</body>

</html>

-----------原型属性的检查

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

/**

* 原型是js中非常特殊一个对象,当一个函数创建之后,会随之就产生一个原型对象

* 当通过这个函数的构造函数创建了一个具体的对象之后,在这个具体的对象中

* 就会有一个属性指向原型

*/

//第一种状态

function Person(){

}

/**

*使用如下方式来编写代码,当属性和方法特别多时,编写起来不是很方便,可以通过json的格式

* 来编写

*/

// Person.prototype.name = "Leon";

// Person.prototype.age = 23;

// Person.prototype.say = function() {

// alert(this.name+","+this.age);

// }

/**

* 以下方式将会重写原型

* 由于原型重写,而且没有通过Person.prototype来指定

* 此时的constructor不会再指向Person而是指向Object

* 如果constructor真的比较重要,可以在json中说明原型的指向

*/

Person.prototype = {

constructor:Person,//手动指定constructor

name:"Leon",

age:23,

say:function() {

alert(this.name+","+this.age);

}

}

var p1 = new Person();

p1.say();

alert(p1.constructor==Person);

</script>

</head>

<body>

</body>

</html>

-------原型重写的问题

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

/**

* 原型是js中非常特殊一个对象,当一个函数创建之后,会随之就产生一个原型对象

* 当通过这个函数的构造函数创建了一个具体的对象之后,在这个具体的对象中

* 就会有一个属性指向原型

*/

//第一种状态

function Person(){

}

var p1 = new Person();

Person.prototype.sayHi = function() {

alert(this.name+":hi");

}

/**

*如果把重写放置在new Person之后,注意内存模型,原型重写的问题.jpg

*/

Person.prototype = {

constructor:Person,//手动指定constructor

name:"Leon",

age:23,

say:function() {

alert(this.name+","+this.age);

}

}

p1.sayHi();//不会报错,但是没有this.name

var p2 = new Person();

//p2.sayHi();//此时p2没有sayHi,所以就会报错

p2.say();

p1.say();

</script>

</head>

<body>

</body>

</html>

------------构造函数和原型同时使用创建对象

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

/**

* 为了解决原型所带来的问题,此处需要通过组合构造函数和原型来实现对象的创建

* 将属性在构造函数中定义,将方法在原型中定义

* 这种有效集合了两者的优点,是目前最为常用的一种方式

*/

function Person(name,age,friends){

//属性在构造函数中定义

this.name = name;

this.age = age;

this.friends = friends;

}

Person.prototype = {

constructor:Person,

//方法在原型中定义

say:function() {

alert(this.name+"["+this.friends+"]");

}

}

//此时所以的属性都是保存在自己的空间中的

var p1 = new Person("Leon",23,["Ada","Chris"]);

p1.name = "John";

p1.friends.push("Mike");//为p1增加了一个朋友

p1.say();

var p2 = new Person("Ada",33,["Leon"]);

//此时原型中就多了一个Mike,这就是原型所带来的第二个问题

p2.say();//leon ada chris mike

</script>

</head>

<body>

</body>

</html>

-----------------------原型和构造函数同时使用问题解决

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

/**

* 为了让定义的方式更加符合java的需求,就把定义方法的原型代码放置到Person这个构造函数中

*/

function Person(name,age,friends){

//属性在构造函数中定义

this.name = name;

this.age = age;

this.friends = friends;

//不能使用重写的方式定义

/*Person.prototype = {

constructor:Person,

//方法在原型中定义

say:function() {

alert(this.name+"["+this.friends+"]");

}

}*/

/**

* 判断Person.prototype.say是否存在,如果不存在就表示需要创建

* 当存在之后就不会在创建了

*/

if(!Person.prototype.say) {

Person.prototype.say = function() {

alert(this.name+"["+this.friends+"]");

}

}

}

//此时所以的属性都是保存在自己的空间中的

var p1 = new Person("Leon",23,["Ada","Chris"]);

p1.name = "John";

p1.friends.push("Mike");//为p1增加了一个朋友

p1.say();

var p2 = new Person("Ada",33,["Leon"]);

//此时原型中就多了一个Mike,这就是原型所带来的第二个问题

p2.say();//leon ada chris mike

</script>

</head>

<body>

</body>

</html>

----------原型链的继承实现以及其中存在的问题

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

/**

* js实现继承的第一种方式是基于原型链的方式

*/

function Parent() {

this.pv = "parent";

this.color = ["red","yellow"];

}

Parent.prototype.pp = "ok";

Parent.prototype.showParentValue = function() {

alert(this.pv);

}

function Child() {

this.cv = "child";

}

/**

* 使用原型链继承,最大的缺点是,无法从子类中调用父类的构造函数

* 这样就没有办法把子类中的属性赋值到父类

* 第二个缺点就是,如果父类中有引用类型,此时这个引用类会添加到

* 子类的原型中,当第一个对象的修改了这个引用之后,其他对象的引用同时修改

* 所以一般都不会单纯的使用原型链来实现继承

*/

Child.prototype = new Parent();

Child.prototype.showChildValue = function() {

alert(this.cv);

}

/**

* 此时完成的对父类对象的覆盖

*/

Child.prototype.showParentValue = function() {

alert("override parent");

}

var c1 = new Child();

//Child中的原型的color被修改

c1.color.push("blue");

alert(c1.color);//red,yellow blue

var c2 = new Child();

alert(c2.color);//red yellow blue

</script>

</head>

<body>

</body>

</html>

--------------------使用call实现继承以及出现的问题

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

function Parent() {

this.color = ["red","blue"];

this.name = "Leon";

}

function Child() {

//在Child中的this明显应该是指向Child的对象

//当调用Parent方法的时候,而且this又是指向了Child

//此时就等于在这里完成this.color = ["red","blue"]

//也就等于在Child中有了this.color属性,这样也就变相的完成了继承

Parent.call(this);

//这种调用方式,就仅仅完成了函数的调用,根本无法实现继承

//Parent();

}

----------------------js的继承完没解决

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

/**

* 组合的实现方式是属性通过伪造的方式实现,方法通过原型链的方式实现

* 注意内存模型

*/

function Parent(name) {

this.color = ["red","blue"];

this.name = name;

}

Parent.prototype.ps = function() {

alert(this.name+"["+this.color+"]");

}

function Child(name,age) {

//已经完成了伪造

Parent.call(this,name);

this.age = age;

}

Child.prototype = new Parent();

Child.prototype.say = function() {

alert(this.name+","+this.age+"["+this.color+"]");

}

var c1 = new Child("Leon",22);

c1.color.push("green");

c1.say();

c1.ps();

var c2 = new Child("Ada",23);

c2.say();

c2.ps();

</script>

</head>

<body>

</body>

</html>

var c1 = new Child();

c1.color.push("green");

alert(c1.color);

var c2 = new Child();

alert(c2.color);

alert(c2.name);

</script>

</head>

<body>

</body>

</html>

/**=============闭包================**/

----------闭包的引入-------------------

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

fn1();

//不会报错,对于通过function fn()这种写法来定义的函数,永远都会被最先初始化

function fn1() {

alert("fn1");

}

fn2();

//使用如下方式定义函数,不会被先执行,如果在之前调用该函数就会报错

/**

* 以下函数的定义方式是现在内存中创建了一块区域,之后通过一个fn2的变量

* 指向这块区域,这块区域的函数开始是没有名称的 ,这种函数就叫做匿名函数

*/

var fn2 = function() {

alert("fn2");

}

</script>

</head>

<body>

</body>

</html>

-----------闭包作用域----

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>js01_hello</title>

<meta name="author" content="Administrator" />

<script type="text/javascript">

/**

* 在js中当进行函数的调用,会为每一个函数增加一个属性SCOPE,通过这个属性来指向一块内存

* 这块内存中包含有所有的上下文使用的变量,当在某个函数中调用了新函数之后,新函数依然

* 会有一个作用域来执行原有的函数的SCOPE和自己新增加的SCOPE,这样就形成一个链式结构

* 这就是js中的作用域链

*/

var color = "red";

var showColor = function() {

alert(this.color);

}

function changeColor() {

var anotherColor = "blue";

function swapColor() {

var tempColor = anotherColor;

anotherColor = color;

color = tempColor;

}

swapColor();

}

changeColor();

showColor();

</script>

</head>

<body>

</body>

</html>