-
Notifications
You must be signed in to change notification settings - Fork 0
/
SimulateNewObject.html
293 lines (234 loc) · 11.4 KB
/
SimulateNewObject.html
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
<!DOCTYPE HTML>
<html lang="zh-CN">
<head>
<title>模拟new object(关于arguments、call、apply)</title>
<meta charset="utf-8">
<meta name="description" content="用面向对象的方式来编写一段命令模式">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> -->
</head>
<body>
<h1>模拟new object(关于arguments、call、apply)</h1>
<pre id="div1">
function Person(name) {
this.name = name;
};
Person.prototype.getName = function () {
return this.name;
};
var objectFactory = function () {
console.log(arguments);
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log("遍历对象的可枚举属性,包括自有属性、继承自原型的属性")
for (p in arguments) { // 遍历对象的可枚举属性,包括自有属性、继承自原型的属性
console.log(p)
console.log(arguments[p])
console.log("--------------")
}
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log("Object.keys 对象自有的可枚举属性")
console.log(Object.keys(arguments)); //对象自有的可枚举属性,
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log("Object.getOwnPropertyNames 返回对象的自有属性,包括可枚举和不可枚举的")
console.log(Object.getOwnPropertyNames(arguments)); //返回对象的自有属性,包括可枚举和不可枚举的
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log("arguments['0']")
console.log(arguments["0"])
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log("arguments['1']")
console.log(arguments["1"])
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log('arguments["length"]')
console.log(arguments["length"])
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log('arguments["callee"]')
console.log(arguments["callee"])
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
// var args = [];
// Array.prototype.push.apply( args, arguments );
// console.log(args);
var obj = new Object(); // 从 Object.prototype上克隆一个空的对象
//shift 返回数组原来的第一个元素的值。
//call() 它的第一个参数用作 this 的对象。其他参数都直接传递给函数自身
//原本是对[]进行shift操作,由于call存在,shift的操作对象this指向了 arguments
//arguments.shift(), 直接操作报错,因为arguments不是一个真正的数组
//[],空数组,只是为了调用shift方法, 可以是任意数组,如[666,777,888]
//其实相当于 Constructor = arguments[0],区别在于,使用shift后,原对象arguments改变了
var Constructor = [].shift.call(arguments); // 取得外部传入的构造器,此例是Person
obj.__proto__ = Constructor.prototype;
// 指向正确的原型
//apply() 方法有两个参数,用作 this 的对象和要传递给函数的参数的数组
//arguments 是被shift改变后的参数,去除了Person,只剩下参数
var ret = Constructor.apply(obj, arguments); // 借用外部传入的构造器给obj设置属 性
return typeof ret === 'object' ? ret : obj; // 确保构造器总是会返回一个对象
};
var a = objectFactory(Person, 'sven');
console.log(Object.getPrototypeOf(a) === Person.prototype); // 输出:true
</pre>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</body>
<script type="text/javascript">
function Person(name) {
this.name = name;
};
Person.prototype.getName = function () {
return this.name;
};
var objectFactory = function () {
console.log(arguments);
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log("遍历对象的可枚举属性,包括自有属性、继承自原型的属性")
for (p in arguments) { // 遍历对象的可枚举属性,包括自有属性、继承自原型的属性
console.log(p)
console.log(arguments[p])
console.log("--------------")
}
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log("Object.keys 对象自有的可枚举属性")
console.log(Object.keys(arguments)); //对象自有的可枚举属性,
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log("Object.getOwnPropertyNames 返回对象的自有属性,包括可枚举和不可枚举的")
console.log(Object.getOwnPropertyNames(arguments)); //返回对象的自有属性,包括可枚举和不可枚举的
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log("arguments['0']")
console.log(arguments["0"])
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log("arguments['1']")
console.log(arguments["1"])
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log('arguments["length"]')
console.log(arguments["length"])
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log('arguments["callee"]')
console.log(arguments["callee"])
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
// var args = [];
// Array.prototype.push.apply( args, arguments );
// console.log(args);
var obj = new Object(); // 从 Object.prototype上克隆一个空的对象
//shift 返回数组原来的第一个元素的值。
//call() 它的第一个参数用作 this 的对象。其他参数都直接传递给函数自身
//原本是对[]进行shift操作,由于call存在,shift的操作对象this指向了 arguments
//arguments.shift(), 直接操作报错,因为arguments不是一个真正的数组
//[],空数组,只是为了调用shift方法, 可以是任意数组,如[666,777,888]
//其实相当于 Constructor = arguments[0],区别在于,使用shift后,原对象arguments改变了
var Constructor = [].shift.call(arguments); // 取得外部传入的构造器,此例是Person
obj.__proto__ = Constructor.prototype;
// 指向正确的原型
//apply() 方法有两个参数,用作 this 的对象和要传递给函数的参数的数组
//arguments 是被shift改变后的参数,去除了Person,只剩下参数
var ret = Constructor.apply(obj, arguments); // 借用外部传入的构造器给obj设置属 性
return typeof ret === 'object' ? ret : obj; // 确保构造器总是会返回一个对象
};
var a = objectFactory(Person, 'sven');
console.log(Object.getPrototypeOf(a) === Person.prototype); // 输出:true
class Animal {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
class Dog extends Animal {
constructor(name) {
super(name);//super关键字用于访问和调用一个对象的父对象上的函数。
}
speak() {
return "woof";
}
}
var dog = new Dog("Scamp");
console.log(dog.getName() + ' says ' + dog.speak());
window.name = 'globalName';
var myObject = {
name: 'sven',
getName: function () {
console.log(this.name);
}
};
myObject.getName();//sven
var getName = myObject.getName;
getName();//globalName
console.log('------------------------------------');
window.name1 = 'MyClassGlobalName';
var MyClass777 = function () {
console.log("MyClass Fun : this.name = " + this.name1);
console.log(this === window);
this.name1 = 'MyClassSven';
};
MyClass777();
var a = {
MyClass777: MyClass777,
name1: "6666666"
}
a.MyClass777();
//构造器的外表跟普通函数一模一样,它们的区别在于被调用的方式
function MyClassHello() {
this.name2 = 'Hello';
};
var obj = new MyClassHello();
console.log(MyClassHello.name); // 输出:MyClassHello
console.log(MyClassHello.name2); // 输出:undefined
console.log(obj.name); // 输出:undefined
console.log(obj.name2); // 输出:Hello
var obj1 = {
objName: 'obj1sven',
getName: function () {
return this.objName;
}
};
var obj2 = {
objName: 'obj2anne'
};
console.log(obj1.getName()); // 输出:obj1sven
console.log(obj1.getName.call(obj2));// 输出:obj2anne
var lostThis = obj1.getName;
console.log(lostThis()); // 输出:undefined
console.log('------------------------------------');
document.getElementById = (function (func) {
return function () {
return func.apply(document, arguments);
}
})(document.getElementById);
//以上的 普通写法是
// var func=document.getElementById;
// document.getElementById = function () {
// return func.apply(document, arguments);
// };
var getId = document.getElementById;
var div = getId('div1');
console.log(div.id); // 输出: div1
console.log('----------------闭包--------------------');
var nodes = document.getElementsByTagName('div');
for (var i = 0, len = nodes.length; i < len; i++) {
//nodes[i].onclick = function () { alert(i); }
eval("nodes[" + i + "].onclick = function () { alert(" + (i + 1) + "); }");
};
var Type = {};
for (var i = 0, type; type = ['String','Array', 'Number'][i++];) {
(function (type) {
Type['is' + type] = function (obj) {
return Object.prototype.toString.call(obj) ==='[object ' + type + ']';
}
})(type)
};
Type.isArray([]); // 输出:true
Type.isString("str"); // 输出:true
console.log('------------------------------------');
var report = (function(){
var imgs = [];
return function( src ){
var img = new Image();
imgs.push( img );
img.src = src+"?"+Math.random();
}
})();
report( 'https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=2874596575,4117721376&fm=58&w=258&h=258&img.GIF' );
</script>
</html>