对象
在大多数人的眼里,js是一门面向对象(Object-Oriented)的语言,但是它与其他的语言比如c++,java 这些面向对象语言 略有不同。
!!!艹,说人话
那问几个问题吧:
1.你知道js中对象的定义是什么吗?
答: 不就是一个散列表嘛~ 相当于key/value对.
var obj = {
name:"jimmy",
gender:"male"
}
2.那js里面一切都是对象你能理解吗?具体一点,你说一下,函数为什么是对象吧。
答:...。 (Ps:md!!! 函数哪里是对象了。。。)
以上对话其实是一道面试题。 是不是感觉自己蒙蒙哒了~
壮士磨叽, 其实js里面一切都是对象是完全有理有据的。希望能够好好理解,因为这个以后可能会区别你是砖家,还是专家的一个重要分水岭.
来我们先说一说对象.
what's the Object?
这个问题就涉及了对象的定义。 上面说的没错,对象其实就是一个散列表而已。但是更深层次的说,你怎么获得一个对象。
show me u code:
var obj = new Object();
上面一个例子很好的体现出,对象如何定义。
对象其实是由 new + 构造函数 创建的。 关于这点就会涉及到模式的概念,大家有兴趣可以参考我前面一篇文章——"模式之辩". 而且还有一个限制, 你所创建的类型必须是引用类型。
听不懂了吧~
总结下上面的,其实
对象 = new + 构造函数 || 字面量的引用类型
来上个栗子.
var obj = new Function(); //对象
var obj = new Object(); //对象
var obj = {}; //对象
var str = "not a Object"; //不是对象
由于string不是引用类型,所以它创建的实例不是对象~ 而且其他的都是引用类型,所以结果都是对象.
但是对象还有几个features, which are unique with other types.
1.对象的可增添性
什么意思嘞?
var obj = {};
obj.name = "jimmy";
console.log(obj.name); //jimmy
var str = "a";
str.name = "jimmy";
console.log(str.name); //undefined
这个可以充分的说明,对象类型和值类型的区别的。
2.等价判断
怎么判断两个对象是一个东西嘞?
用"==="呗。 来试一试.
var obj1 = new Object();
var obj2 = new Object();
console.log(obj1===obj2); //false
艹,怎么会这样,两个不都是对象吗?而且我又没动它。应该一样啊~~~
骚年,不要把你判断值类型的方法套在我们伟大的对象上。
说明一下。如果判断对象类型和值类型。
对象类型的判断:
对象的等价是建立在你们的源是否相同(官方的说法叫地址).
var obj1= new Object();
var obj2 = new Object();
需要搞清楚,使用 new + 构造器 你是在新建实例,即你创建的是不同源的对象。
那如何同源嘞?
var obj1 = new Object({
name:"jimmy"
});
var obj2 = obj1; //同源
var obj3 = new Object();
obj2.name = "sam";
console.log(obj1.name); //sam
console.log(obj1===obj2); //true
console.log(obj2===obj3); //false
其实到这里,我们需要将我们以前的所说的对象再抽象一层。 你说使用的var obj1 里面的obj1 并不是对象,而只是一个指针, 指向着这个对象。 那这个对象在哪里嘞? 在你的内存当中。 艹~~~ 好难理解。
为了大家更好的理解一切都是对象,我这里会以大众的视角来讲解的。(当然如果你已经理解了,可以忽略下面非正式的说法~)
回退~
我们还是将obj1和obj2说成是对象。 上面可以看出,只有是同源的对象才会相等。
值类型的判断:
这个就很好说了, 你知道1===1吗? 恩,知道~~~
恭喜你,你已经知道值类型的判断了。
var num1 = 2;
var num2 = 2;
console.log(num1===num2); //true
说了这么多,那值类型和引用类型到底有哪些呢?
值类型: string,number,Boolean,null,undefined,Symbol(es6才出的)
引用类型: Object,Array,RegExp,Function,Date
恩,大致就这么多。
~脚嘚玛嘚(Ps:日语)
大哥,不对呀~ 为什么有时候我使用string类型的时候又可以在后面使用方法嘞?您看:
var s = "jimmy";
console.log(s.length); //5
不是说值类型不是对象吗? 那它怎么会有对象的feature呢?
对,这个问题问的好~
来,再给大家科普一个类型,基本包装类型。
基本包装类型
我相信写过2k+代码的童鞋应该会遇到这样的情况。比如我要知道这个字符串是不是空,可以使用这样的判断:
var s = "jimmy";
if(s.length===0){
console.log("这是一个空的string");
}
咦~ 为什么值类型的又可以使用属性嘞?
事实上, ECMAScript 规定的类型详细的分有2.5种.
除了上面说的两种还有一种基本包装类型.
基本包装类型: String,Number,Boolean.
其实值类型 包括基本包装类型的。
那他的特性是什么嘞?
再看一下上面的例子:
var str= "jimmy";
console.log(str.length); //5
str.length = 6;
console.log(str.length); //5
我们用事实说话, 上面的结果很好的证明了,基本包装类型的特性。 即 如果你想读取值类型的相关属性和方法,
js引擎会默认帮你将值类型,临时变为一个对象使用。但是这层保存存在的时间,只是你代码执行的那一瞬间。
再次证明:
var str = "jimmy";
str.male = "male"; //执行成功,但立即被销毁
console.log(str.male); //undefined
上面例子的执行过程是
1.给str包装一层对象实例
2.执行对象的一个特性
3.销毁这层包装实例
所以就不难理解,为什么上面会是undefined. (因为没都没了,你哪来的定义嘞)。
综上所述,在js中一切都是对象是不无道理的。
还记得上面说的,对象是由 new + 构造器函数 创建的吗? 所以说 有构造器的类型,都是对象。 事实上除了null,undefined 这两个 呆毛。 其他的类型都有构造器,所以再次声明一切都是对象是很有道理的。
最后我们来回答一下开篇的那个题目,为什么函数也是对象?
如果函数也是对象,那他应该具有对象的一切特性,我这里偷个懒,就举他的动态特性吧。
function a (){};
a.move = 1;
console.log(a.move); //1
额,不信吗? 我开大了哈~ 用instanceof 检测一下
console.log(a instanceof Object); // true
完毕~
再补充一点,我整篇都是对象对象的。英文不都是Object. 那为什么Function类型也是Object. RegExp类型也是Object. Object 也是Object. 好了 不绕了, 如果大家如果知道原型链这个东西的话,应该知道,所有的构造器的原型的金字塔尖 就是Object. (null不算啊~ 这个呆毛不算,因为Object再往上就是null了);
下次面试之前理解一下这句话,我相信,你的评级应该会靠SP 更近一点吧。嘿嘿
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。