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" lang="en">
<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" id="pwd" />
<br/>
<input type="button" value="获取users" οnclick="getUsers()"/>
<input type="button" value="获取PWD" οnclick="getPwd()"/>
<input type="button" value="获取Input" οnclick="getInputs()"/>
<br/>
<div id="showPwd">
<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" lang="en">
<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 id="content">
<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" οnclick="getAllH1()" />
<input type="button" value="获取content的h2" οnclick="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" lang="en">
<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="点击一下" id="btn"/>
<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" lang="en">
<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="点击一下" id="btn"/>
</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" lang="en">
<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="点击一下" id="btn"/>
</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" lang="en">
<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="点击一下" id="btn"/>
</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" lang="en">
<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" lang="en">
<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" lang="en">
<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" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>js01_hello</title>
<meta name="author" content="Administrator" />

</head>
<body>
<div id="person"></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" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>js01_hello</title>
<meta name="author" content="Administrator" />

</head>
<body>
<div id="person"></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" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>js01_hello</title>
<meta name="author" content="Administrator" />

</head>
<body>
<div id="person"></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" lang="en">
<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" lang="en">
<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" lang="en">
<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" lang="en">
<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" lang="en">
<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" lang="en">
<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" lang="en">
<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" lang="en">
<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" lang="en">
<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" lang="en">
<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" lang="en">
<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" lang="en">
<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" lang="en">
<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" lang="en">
<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" lang="en">
<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>

 

转载于:https://www.cnblogs.com/csy666/p/6791290.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值