例1:
isNaN()判断是否为非数,是非数返回true,否则返回false。
'100’会因为isNaN()内置的包装类自动由String类型转换成number类型
- 依照isNaN原理自建一个myIsNaN
function myIsNaN(num){
var ret = Number(num);//调用包装类
ret += "";
if(ret == "NaN"){
return true;
}else{
return false;
}
}
例2:
var foo = "123";
function print(){
var foo = "456";
this.foo = "789";//改了GO中的foo = "123"
console.log(foo);
}
print();
console.log(foo);
例2变形:
var foo = 123;
function print(){
this.foo = 234;//AO里面没有foo,所以这里的this==>window
console.log(foo);//234//打印的也是window.foo
}
print();
例2变形变形:
var foo = 123;
function print(){
// var this = Object.create(print.prototype)
//这里的this不指代window,所以window.foo不会变为234
this.foo = 234;
console.log(foo);//123!123!123!//AO中没有foo变量,所以也是window.foo
console.log(this.foo);//234
}
new print();
例3:
var name = "222";
var a = {
name : '111',
say : function(){
console.log(this.name);
}
}
var fun = a.say;
fun();//222
a.say();//111
var b = {
name : "333",
say : function (fun){
fun();
}
}
b.say(a.say);//222!222!222!
b.say = a.say;
b.say();//333
- 精解
b.say(a.say);//222!222!222!
这种情况与var fun = a.say;fun();原理一样
var name = "222";
var a = {
name : '111',
say : function(){
console.log(this.name);
}
}
var fun = a.say;
var b = {
// this --> b
name : "333",
say : function (fun){ //fun = a.say
fun();//函数执行,无人调用,就是预编译情况:window调用
// function(){
// console.log(this.name);
// }
// 如果是以下情况:函数执行,b调用
// this.fun();
}
}
b.say(a.say);//222!222!222!
例4:
var a = 5;
function test(){
a = 0;
alert(a);//0
alert(this.a);//5
var a;
alert(a);//0
}
test();
例4变形:
var a = 5;
function test(){
// var this = {
// __proto__:test.prototype
// }
a = 0;
alert(a);//0
alert(this.a);//undefined!undefined!undefined!
// this上没有a属性,所以打印undefined
var a;
alert(a);//0
}
new test();
例5:
// 考预编译题:
function print(){
console.log(foo);//undefined!undefined!undefined!
var foo = 2;
console.log(foo);//2
console.log(hello);//undefined//Uncaught ReferenceError: hello is not defined
}
print();
例6:
// 考隐式类型转换:
(function (){
var x = 1;
if(x == "1"){
console.log("One!");//One!
}
if(x === "1")
console.log("Twe!");
}())
例7:
例8:
(function(){
var marty = {
name:"marty",
printName:function(){console.log(this.name);}
}
var test1 = {name:"test1"};
var test2 = {name:"test2"};
var test3 = {name:"test3"};
test3.printName = marty.printName;//test3中+printName:function(){console.log(this.name)
var printName2 = marty.printName.bind({name:123});//function(){console.log(this.name).bind({name:123})//123
marty.printName.call(test1);//function(){console.log(this.name).call(test1);//test1
marty.printName.apply(test2);//function(){console.log(this.name).apply(test2);//test2
marty.printName();//marty
printName2();//123
test3.printName();//test3
}())
例9:
var bar = {a:'002'};
function print(){
bar.a = 'a';
Object.prototype.b = 'b';
return function inner(){ //形成闭包
console.log(bar.a);//a
console.log(bar.b);//b
}
}
print()();//执行闭包
克隆作业——浅层克隆
//浅层克隆:B由A克隆而来,但是B和A仍会互相影响,即引用值公用一个空间问题
var A = {
name:'abc',//原始值
age:18,
sex:'male',
card:['visa','unionpay']//引用值
}
var B = {}
function clone(target,origin){
//优化:如果客户提供了目标函数就使用客户的,如果没提供就自己生成一个目标函数,最后返回
var target = target || {};
for(var prop in origin){
target[prop] = origin[prop];
}
return target;
}
clone(B,A);
克隆作业——深层克隆
- A的属性克隆到B身上之后,A和B就完全是两个独立的个体
- 深层克隆:B由A克隆而来,但是B和A仍然不会互相影响
自己写的版本:
// var A = {
// name:'abc',
// age:18,
// sex:'male',
// card:['visa','unionpay',['a']],
// grade:{first:2017}
// }
// var B = {}
// function clone(target,origin){
//优化:如果客户提供了目标函数就使用客户的,如果没提供就自己生成一个目标函数,最后返回
// var target = target || {};
// for(var prop in origin){
// 筛选出引用值的内容
// if(typeof origin[prop] == 'object'){
//筛选出数组,开始分析数组,可以考虑用闭包+立即执行函数
// if(origin[prop] instanceof Array){
//问题在于我怎么那才不是那他的引用值?
//2.0
// {
// var arr = [];
// clone(arr,origin[prop]);
// target[prop] = arr;
// }
//
// {1.0
// for(i = 0; i < origin[prop].length; i++){
// arr[i] = origin[prop][i];
// }
// }
// }else{//筛选出对象,开始分析对象
// var temp = {};
// clone(temp,origin[prop]);
// target[prop] = temp;
// }
// }else{
// target[prop] = origin[prop];
// }
// }
// return target;
// }
// clone(B,A);
标准版本:
//遍历对象
// 1.判断原始值还是引用值
// 2.引用值:判读是数组还是对象
// 3.建立相应新数组或新对象
var A = {
name:'abc',//原始值
age:18,
sex:'male',
card:['visa','unionpay',['a']],
grade:{first:2017}
}
var B = {}
function deepClone(origin,target){
var target = target || {},//容错设置
toStr = Object.prototype.toString,
arrStr = "[object Array]";
for(var prop in origin){
if(origin[prop] !== 'null' && origin.hasOwnProperty(prop)){//排除系统(原型)属性
if(typeof origin[prop] == 'object'){//处理引用值
//版本一:
// {
// if(toStr.call(origin[prop]) == arrStr){
// target[prop] = [];
// }else{
// target[prop] = {};
// }
// }
//版本二:
target[prop] = (toStr.call(origin[prop]) == arrStr) ? [] : {};
deepClone(origin[prop],target[prop]);
}else{//处理原始值
target[prop] = origin[prop];
}
}
}
return target;
}
deepClone(A,B)