js类型深究

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>

<body>
<script>
function Person(name, age) {
this.name = name;
this.age = age;
console.log(this);

}
Person(‘wang‘, 18)


// 简易表面模拟 函数工厂
function person(name, age) {
var that = {}
that.name = name;
that.age = age;
console.log(that);
return that;
}

var person1 = person(‘zhang‘, 10)
var person2 = person(‘Li‘, 20)

// 冷门知识 刻意返回引用值

function Fn(name, age) {
this.name = name;
this.age = age;
return {}

}
console.log(new Fn(‘wang‘, 18));

// 刻意返回原始值
function Fn1(name, age) {
this.name = name;
this.age = age;
return 124

}
console.log(new Fn1(‘wang‘, 18));

// string等引用值是有坚决不能赋值属性的机制的
var num = 123;
num.len = 2;
console.log(num.len); // 这里不会报错,是因为发生了以下操作

// 分析
var num = 123;
num.len = 2; // 这里底层发现 引用值不能被赋属性值 所以js为防止你错误使用 new Number(123).len = 2; 然后进行销毁
console.log(num
.len
); // 然后到了这里你再次访问 js引擎发现你还是不长记性 于是又给你new Number(123);这里和上一个new Number不是同一个,于是你访问这个new Number(123)的len属性的时候,是没值的,于是返回underfined;
// 说白了 引用值string 和 number是没有getter和setter的,就是js做了处理 当你访问这种引用类型的属性的时候给你new了一个对应的包装类而已


// 进阶:比如出个面试题:问你打印的结果是什么
var arr = [1, 2, 3, 4]
arr.length = 2;
console.log(arr); // 结果为[1,2] 进行了截断
var str = ‘abcd‘
str.length = 2;
console.log(str); // ?


// 我们来看分析
var str = ‘abcd‘ // js由值决定类型,这里是原始值 string类型
str.length =
2; // js引擎发现原始值不能进行属性访问 为了防止报错 内部进行了new String(‘abcd‘).length的访问和赋值 最后会进行delete销毁,因为并不会使用只是为了防止报错 那么length等于2 截断的是new String(‘abcd‘)的结果
console.log(str); // 所以访问这里 还是原来的‘abcd‘

// 最后小曹如果觉得同学们还要再争辩的话,可以看看下一个打印
console.log(str
.length
); // 这里你不要猜了 日志result为4 前面不是赋值了2吗? 往上面的步骤带一带 除非你非要理解这个length是字符串和数组独特的js原始属性,封装在String和Array的原型上,只不过给string的set方法给禁止了 或者Object.freeze() 那你知道原型了应该知道new String()的步骤了 一个是string实例一个是string包装类 所以你回过头会想明白的


// 扩展:
//  请确认以下的判断是否准确str1 === yiifaa//str2 === yiifaa//typeof str1 === typeof str2
var yiifaa = ‘yiifaa‘,
str1 = new String(yiifaa),
str2 = String(yiifaa)
/*根据JS的语法,要满足===的条件如下:
1. 如果是引用类型,则两个变量必须指向同一个对象(同一个地址);
2. 如果是基本类型,则两个变量除了类型必须相同外,值还必须相等。
再把话题切换到String对象上来,String的声明方式有三种(请参见第一段代码),但产生的类型却不尽相同,结果如下:
//  类型为string,为基本类型typeof yiifaa//  类型为object,为引用类型typeof str1//  类型为string,为基本类型typeof str2
// 那现在答案很清楚了,如下: false, 因为str1为引用类型str1 === yiifaa//  true, 因为都是基本类型,并且值相等str2 === yiifaa// false, 虽然都是字符串,但分别为object与stringtypeof str1 === typeof str2

*/


/*总结:
很神奇的String对象,一方面可以作为基本类型,另一方面还可以作为引用类型,更神奇的是,为String.prototype添加方法,基本类型还可以引用到,怎么做到的?

对比JAVA的Integer对象的实现,利用int声明的变量可不能调用Integer的方法,所以还不是装箱操作。

最后关于一个函数既可以作为普通函数调用,也可以作为构造函数调用,实现方法如下:*/
function User(username) {
this.username =
username //  这肯定是作为函数调用,但在服务端判断需要改进  
//  必须要进行判断,否则死循环   
if (this === window) {
return new User(username)
}
}
// 改进的方法如下:
function User(username) { //  一定是调用了构造函数   
if (this.inst === "User") {
this.username = username
} else {
return new User(username)
}
}
//  为User的上下文添加标记User.prototype.inst = "User"
</script>
</body>

</html>

js类型深究

上一篇:全(五)Jmeter 之 参数类型 分为三种:参数(parameters)类型、消息体数据(bodydata)类型、文件上传(Files Upload)类型


下一篇:分析.Net里线程同步机制