标签:处理 last 文字 head cto 内容 面向对象语言 png 没有
主要内容
值类型与引用类型的特征
深拷贝与浅拷贝
对象的动态特性
构造函数的执行过程
异常处理
dom操作(略)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script>
var car = { name: ‘法拉利‘,
deepCopy: function() {
// 假设 copy 已经写好
// 1, 创建一个对象
var temp = {};
// 2, 拷贝属性, 在判断如果是引用类型需要深拷贝
for ( var k in this ) {
if ( typeof this[ k ] === ‘object‘ ) {
temp[ k ] = this[ k ].deepCopy();
} else {
temp[ k ] = this[ k ];
}
}
// 3, 返回对象
return temp;
}
};
var p = { name: ‘张三‘, car: car,
deepCopy: function () {
// 1, 创建一个对象
var temp = {};
// 2, 拷贝属性, 在判断如果是引用类型需要深拷贝
for ( var k in this ) {
if ( typeof this[ k ] === ‘object‘ ) {
temp[ k ] = this[ k ].deepCopy();
} else {
temp[ k ] = this[ k ];
}
}
// 3, 返回对象
return temp;
}
}
// 需要保证所有的 对象中 都有 copy 方法 那么就可以简化了
// 写一个 deepCopy 函数, 每一个对象都是用 <对象>.deepCopy = deepCopy
// 来使得当前对象具有 拷贝的方法, 那么就可以实现深拷贝了
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script>
var deepCopy = function () {
// 1, 创建一个对象
var temp = {};
// 2, 拷贝属性, 在判断如果是引用类型需要深拷贝
for ( var k in this ) {
if ( typeof this[ k ] === ‘object‘ ) {
temp[ k ] = this[ k ].deepCopy();
} else {
temp[ k ] = this[ k ];
}
// temp[ k ] = this[ k ];
}
// 3, 返回对象
return temp;
}
var car = { name: ‘法拉利‘ };
var p = { name: ‘张三‘, age: 19, gender: ‘男‘, car: car };
// 让所有的对象都有 拷贝的 方法
car.deepCopy = deepCopy;
p.deepCopy = deepCopy;
var newP = p.deepCopy();
p.name = ‘李四‘;
p.age = 20;
p.gender = ‘女‘;
p.car.name = ‘兰博基尼‘;
</script>
</html>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script>
var car = { name: ‘法拉利‘ };
var p = { name: ‘张三‘, age: 19, car: car };
// var pCopy = p; // 这个不是拷贝, 没有对对象做任何拷贝行为
// 浅拷贝的代码实现
// var pCopy = {};
// pCopy.name = p.name;
// pCopy.age = p.age;
// pCopy.car = p.car;
// 深拷贝的代码实现
var pCopy = {};
pCopy.name = p.name;
pCopy.age = p.age;
pCopy.car = {};
pCopy.car.name = p.car.name;
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script>
function Person () {
this.name = ‘张三‘;
this.age = 19;
this.gender = ‘男‘;
}
var p = new Person();
</script>
</html>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script>
var deepCopy = function () {
// 1, 创建一个对象
var temp = {};
// 2, 拷贝属性, 在判断如果是引用类型需要深拷贝
for ( var k in this ) {
if ( typeof this[ k ] === ‘object‘ ) {
temp[ k ] = this[ k ].deepCopy();
} else {
temp[ k ] = this[ k ];
}
// temp[ k ] = this[ k ];
}
// 3, 返回对象
return temp;
}
var car = { name: ‘法拉利‘ };
var p = { name: ‘张三‘, age: 19, gender: ‘男‘, car: car };
// 让所有的对象都有 拷贝的 方法
car.deepCopy = deepCopy;
p.deepCopy = deepCopy;
var newP = p.deepCopy();
p.name = ‘李四‘;
p.age = 20;
p.gender = ‘女‘;
p.car.name = ‘兰博基尼‘;
</script>
</html>

--------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------
主要内容
DOM操作
原型的概念
原型属性与原型对象的含义
原型继承的概念
如何使用原型
var o = {};
o.name = ‘jim‘;
o.sayHello = function () {};
构造函数的本质与下面的代码一样
function Person ( o ) {
o.name = ‘jim‘;
o.age = 19;
o.sex = ‘male‘; // 男, female 女
return o;
}
var p = Person( {} );
一开始就是 {}, 然后加属性. 至少要四行代码
var p = {};
p.name = ‘jim‘;
p.age = 19;
p.sex = ‘male‘;
如果有函数, 可以将上面的四句话减为一句话
function createPerson() {
var p = {};
p.name = ‘jim‘;
p.age = 19;
p.sex = ‘male‘;
return p;
}
var per = createPerson();
var p1 = {};
p1.name = p.name;
...
p1.car = {};
p1.car.name = p.car.name;
就是获取元素
父元素.insertBefore( 新元素, 旧元素 );
// 将 新元素 插入到 旧元素 的前面
由于 js 是解释执行的语言, 那么再代码中出现函数与对象如果重复执行, 会创建多个副本
// 1
function Person() {
var o = {};
o.name = ...
return o;
}
// 2
function Person () {
name: ....
age: ....
...
}
function Foo() {
this.sayHello = function () {
}
}
new Foo() 所创建出来的. 因此每一个对象在创建的时候, 函数 sayHello 都会被创建一次{} == {} function sayHello () {}
function Foo () {
this.say = sayHello;
}
var f1 = new Foo();
var f2 = new Foo();
f1.sayHello(); // 如果 f1 没有 sayHello, 那么就会在 Foo.prototype 中去找
f2.sayGoodBye(); // 如果 f2 没有改方法, 那么就会在 Foo.prototype 中去找
只需要将共享的东西, 重复会多占用内存的东西放到 构造函数.prototype 中, 那么所有的对象就可以共享了.
function Foo() {}
Foo.prototype.sayHello = function () {
console.log( ... );
};
var f1 = new Foo();
f1.sayHello();
var f2 = new Foo();
f2.sayHello();
f1.sayHello === f2.sayHello
function Person() {}
Person.prototype.name = ‘张三‘;
var p = new Person();
赋值的错误
function Person() {}
Person.prototype.name = ‘张三‘;
var p1 = new Person();
var p2 = new Person();
p1.name = ‘李四‘;
console.log( p1.name );
console.log( p2.name );
// 如果是访问数据, 当前对象中如果没有该数据就到构造函数的原型属性中去找
// 如果是写数据, 当对象中有该数据的时候, 就是修改值; 如果对象没有该数据, 那么就添加值
// 在 java 中, 最小的代码单位是 类
class Program {
// 成员
}
为什么使用原型?
Student.prototype = {
sayHello: function () {},
study: function () {}
};
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script>
function Person () {}
var p = new Person();
// 1. 执行 new 创建 对象
// 2. 执行构造函数 Person 初始化对象( 给对象添加属性 )
// 3. 赋值给 变量 p
// 现在 p 表示的对象 默认连接到 Person.prototype
Person.prototype.good = function () { alert ( ‘好‘ ); };
p.good();
</script>
</html>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script>
function Person () { }
Person.prototype.func = function () {
console.log( ‘11111‘ );
};
var p1 = new Person();
Person.prototype = {
func: function () {
console.log( ‘22222‘ );
}
};
var p2 = new Person();
p1.func();
p2.func();
</script>
</html>
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
答疑DOM内容
__proto__
原型继承的概念
混合式继承
绘制构造原型实例三角形
属性搜索原则
静态成员与实例成员
1. 复习
删除子元素
// 从 node 中删除 一个 div
node.removeChild( div );
// 如果 div 变量不存在
var div = document.getElementById( ‘...‘ );
node.removeChild( div );
// 假设 node 节点中只有一个元素 div
node.innerHTML = ‘‘;
删除属性
var attrNode = node.getAttributeNode( ‘属性名‘ );
node.removeAttributeNode( attrNode );
// removeAttribute 是什么意思呢?
node.removeAttribute( ‘属性名‘ );
// getAttributeNode
// getAttribute
获取属性值
var attrNode = node.getAttributeNode( ‘属性名‘ );
attrNode.nodeValue;
// 简化
node.getAttribute( ‘属性名‘ );
作业
画 DOM 树
table 表格案例
<html>
<head>
<title>文本</title>
<meta charset="utf-8" />
</head>
<body>
<div>
111111<span style="color: red;">22222</span>3333</div>
</body>
</html>
2. proto
以前要访问原型, 必须使用构造函数来实现. 无法直接使用实例对象来访问原型. 火狐最早引入属性 __proto__ 表示使用实例对象引用原型. 但是早期是非标准的. 通过该属性可以允许使用实例对象直接访问原型
function Person() {}
// 神秘对象就是 Person.prototype
// 那么只有使用 构造函数 才可以访问它
var o = new Person();
// 以前不能直接使用 o 来访问神秘对象
// 现在有了 __proto__ 后
// o.__proto__ 也可以直接访问神秘对象( 两个下划线 )
// 那么 o.__proto__ === Person.prototype
神秘对象中默认都有一个属性 constructor, 翻译为 构造器. 表示该原型是与什么构造函数练习起来的.
__proto__ 有什么用?
可以访问原型
由于在开发中除非特殊要求, 不要使用实例去修改原型的成员. 因此属性开发时使用较少
但是再调试过程中非常方便, 可以轻易的访问原型进行查看成员
如果在 早期的浏览器中使用 实例需要访问原型如何处理?
可以使用实例对象访问 构造器, 然后使用构造器访问原型
var o = new Person();
o.constructor.prototype
如果给实例继承自原型的属性赋值
function Foo() {}
Foo.prototype.name = ‘test‘;
var o1 = new Foo();
var o2 = new Foo();
o1.name = ‘张三‘; // 不是修改原型中的 name 而是自己增加了一个 name 属性
console.log( o1.name + ‘, ‘ + o2.name );
3. 继承
最简单的继承就是 将别的对象的属性强加到 我的 身上, 那么我就有这个成员了.
利用原型也可以实现继承, 不需要在我的身上添加任何成员, 只要原型有了, 我就有了.
结论:
将属性, 方法等成员利用 混入的办法, 加到构造函数的原型上, 那么构造函数的实例就都具有该方法了.
3.1. 混合式继承复杂描述
new DivTag() 用来 创建 div 对象
appendTo 加到某元素上
扩展
img
p
span
a
...
无论方法怎么写, 方法是谁调用的, this 就是谁
4. 面试题
将字符串中 >, <, &, TM, 空格, ...
逻辑中断
// foo = foo || bar;
// || 逻辑或, 左边如果为真, 那么整个表达式的值 就是 左边的值
// || 如果 左边的值为 假, 那么整个表达式的值就是右边的值
// 如果考虑函数参数的时候, 一般使用 该 方法来兼容处理参数
div.onclick = function ( e ) {
e = e || window.event;
};
变量名提升
5. 中午复习
function Person() {}
var p1 = new Person();
var p2 = new Person.prototype.constructor();
6. 细节
使用点语法给原型添加成员与使用直接替换修改原型对象有什么区别?
原型指向发生了变化
构造函数所创建的对象所继承的原型不同
新增的对象默认是没有 constructor 属性
注意: 在使用替换的方式修改原型的时候, 一般都会添加 constructor 属性.
function Person() {}
Person.prototype = {
constructor: Person
};
// 拆解
function Person() {}
var o = {};
o.costructor = Person; // 属性中就存储着函数的地址
Person.prototype = o;
Person = 123;
7. 静态成员与实例成员的概念
也是从 面向对象的 变成语言中引入的
静态成员表示的是 静态方法和 静态属性的概念. 所谓的静态, 就是由构造函数所提供的.
实例成员表示的是 实例方法 和 实例属性. 所谓的实例就是由构造函数所创建的对象.
一般工具型方法都有静态成员提供, 一般与实例对象有关的方法由实例成员表示.
8. 三角形绘图
练习:
// 1
function Person() {
this.name = ‘张三‘;
this.sayHello = function () {
}
}
var p = new Person();
// 2
function Person() {
this.name = ‘张三‘;
}
Person.prototype.sayHello = function () {
}
var p = new Person();
// 3
function Person() {
this.name = ‘张三‘;
}
Person.prototype = {
sayHello: function () {
}
};
var p = new Person();
9. 原型与继承小结
什么是原型?
如何使用原型?
利用点添加成员
直接替换添加成员
什么是原型继承?
实例对象是继承自 原型对象 的
一般的开发方式: 属性交给构造函数, 方法交给原型
如何实现?
混合继承方式: 利用混入的办法给原型添加成员, 那么实例对象就可以继承指定的方法和属性
直接替换原型对象
// 例如要实现一个自定义的集合( 数组 )
// 弄一个类型 ItcastCollection
function ItcastCollection () {}
// 要提供数组的方法为其添加成员
ItcastCollection.prototype = [];
10. 从案例中引出的问题
什么时候会得到 undefined.
我们介绍的是在实例中没有找到, 就去原型中找, 但是原型中没有怎么办?
10.1. 属性搜索原则
原型链
属性搜索原则
所谓的属性搜索原则, 就是对象在访问属性与方法的时候, 首先在当前对象中查找
如果当前对象中存储在属性或方法, 停止查找, 直接使用该属性与方法
如果对象没有改成员, 那么再其原型对象中查找
如果原型对象含有该成员, 那么停止查找, 直接使用
如果原型还没有, 就到原型的原型中查找
如此往复, 直到直到 Object.prototype 还没有, 那么就返回 undefied.
如果是调用方法就包错, 该 xxxx 不是一个函数
11. 作业
构造函数的执行过程分析( 要求使用文字将每一句话的执行描述出来 )
// 1
function Person() {
this.name = ‘jim‘;
this.sayHello = function () {
console.log( ‘hello‘ );
}
}
var p = new Person();
// 2
function Student( name, age ) {
this.name = name;
this.age = age;
}
Student.prototype = {
sayHello: function () {
console.log( ‘hello‘ );
}
};
var p = new Student( ‘张三‘, 19 );
自己定义 DivTag 与 PTag 构造函数, 完成 元素的添加. 要求使用原型继承
绘制内存逻辑图
// 1
function Person() {
this.name = ‘张三‘;
this.sayHello = function () {
}
}
var p = new Person();
var q = new Person();
// 2
function Person() {
this.name = ‘张三‘;
}
Person.prototype.sayHello = function () {
}
var p = new Person();
var q = new Person();
// 3
function Person() {
this.name = ‘张三‘;
}
Person.prototype = {
sayHello: function () {
}
};
var p = new Person();
var q = new Person();
复述属性搜索原则
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script>
var data = [
{ name: ‘jim1‘, age: 19, gender: ‘male‘ },
{ name: ‘jim2‘, age: 29, gender: ‘female‘ },
{ name: ‘jim3‘, age: 39, gender: ‘male‘ },
{ name: ‘jim4‘, age: 49, gender: ‘male‘ },
{ name: ‘jim5‘, age: 59, gender: ‘male‘ }
];
// 创建表格
// 1, 创建 table + tbody + thead
// 2, 创建 tr + th
// 3, 创建每一行的 hr + td
// 4, 加到页面中
// 1
var table = document.createElement( ‘table‘ );
var thead = document.createElement( ‘thead‘ );
var tbody = document.createElement( ‘tbody‘ );
table.appendChild( thead );
table.appendChild( tbody );
// 2
var trHead = document.createElement( ‘tr‘ );
thead.appendChild( trHead );
for ( var k in data[ 0 ] ) {
// k 就是 th 的内容
var th = document.createElement( ‘th‘ );
th.appendChild( document.createTextNode( k ) );
trHead.appendChild( th );
}
// 3
for ( var i = 0; i < data.length; i++ ) {
var tr = document.createElement( ‘tr‘ );
for ( var k in data[ i ] ) {
var td = document.createElement( ‘td‘ );
td.appendChild( document.createTextNode( data[ i ][ k ] ) );
tr.appendChild( td );
}
tbody.appendChild( tr );
}
table.border = 1;
//
document.body.appendChild( table );
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script>
function Person ( name ) {
this.name = name;
}
var p = new Person( ‘jim‘ );
</script>
</html>

| 【作者】:轻轻走143 |
| 【出处】:http://www.cnblogs.com/qingqingzou-143/ |
| 【声明】:所有博文标题后加(share)的表示收集的他人优秀文章,其余的则为原创。欢迎转载,但请在显要位置显示本文链接,并保留本段声明,否则追究法律责任,谢谢! |
标签:处理 last 文字 head cto 内容 面向对象语言 png 没有
原文地址:http://www.cnblogs.com/qingqingzou-143/p/6180839.html