javascript 的值和引用 函数与对象(function object)

javascript 只有6种基本类型

数据类型含义值/引用备注
undefined未定义没有值
number数字 
boolean布尔 
string字符串字符串在赋值运算中会按照引用的方式来处理
function方法引用 
object对象引用 

一般表达式运算结果总是值

函数/方法的返回值可以是值或者引用

两个引用之间如果等值(==),则一定全等(===)

值与引用, 值与值 之间, 即使值相等(==), 也不一定全等(===)

[==在比较的时候可以转换数据类型,===严格比较,只要类型不匹配就返回flase]

然后我们来看函数和对象, javascript是一种基于对象的语言,所有对象的原型(prototype)都是Object

instanceof是一个二元运算符,如:A instanceof B. 其中,A必须是一个合法的JavaScript对象,B必须是一个合法的JavaScript函数 (function)

如果函数B在对象A的原型链 (prototype chain) 中被发现,那么instanceof操作符将返回true,否则返回false.

换句话说就是 就是测试  对象A的__proto__ 属性是否指向函数B的prototype链 ( 对象A是由函数B创建的 )

每个函数默认都会有一个属性叫prototype,

每一个通过函数和new操作符生成的对象都具有一个属性__proto__ 这个属性保存了创建它的构造函数的prototype属性的引用

结合上图就是 f1 和 f2 是由Foo 方法创建的, o1 和 o2 是由 Object方法创建的

所以

console.log(obj instanceof Object)//true

console.log(fn instanceof Function)//true

然后尝试下面的代码

function fn(){}

var obj = {}

console.log(fn instanceof Object)//true

console.log(obj instanceof Function)//false

console.log(Function instanceof  Object); // true

console.log(Object instanceof Function);  // true

fn是由Foo方法创建的,然后Foo.prototype指向Object.prototype, 所以 fn instanceof Object为true

obj是由Object方法创建的,但是Object.prototype并没有指向Function.prototype, 所以返回是false

Function对象的__proto__指向了Object(方法).prototype, 也就是说Function对象是由Object方法创建的,所以返回的是true

后面两个麻烦一点

console.log(Function);    
console.log(Object);

返回

function Function() { [native code] }
function Object() { [native code] }

可以看到这两个东西实际上都是函数,一个是Function()函数,一个是Object()函数

参考 如果函数B在对象A的原型链 (prototype chain) 中被发现,那么instanceof操作符将返回true,否则返回false.

所有函数(上图中的Foo(),Object()和Function())的__proto__ 都是Function.prototype

其实图很清楚,最关键的是你一定要记住instanceof左边的是对象,右边的是函数,这个关键字其实只是测试

        左边的对象的__proto__是否可以关联到右边创建它的函数的prototype

console.log(Function instanceof  Object); // true

console.log(Object instanceof Function);  // true

这两行代码中的第一行Function是对象(函数对象) , Object是类型

第二行中的Object是对象(还是函数对象) , Function是类型

通过上面的内容可以很好理解为什么通过

var fcuntion1 = function(){};  //调用function()函数获得

var fcuntion 2 = new Function();  //Function被new的时候还是调用function

都可以创建一个函数对象, 因为Function类型的constructor就是function(){}

如果你觉得上面的所有内容都不够”变态”, 实际上我们可以做得更”变态”一点

那就是__proto__属性其实是可以被重写的, 这意味着使用它时仍然不是那么太安全 ( 当然估计没人会给自己惹这种麻烦 )

function fn(){}
var obj = {}


console.log(obj instanceof Function); //false

obj.__proto__ = Function.prototype;

console.log(obj instanceof Function); // true

在这个”变态”的例子中我不得不提一下typeof

typeof用以获取一个变量或者表达式的类型,typeof一般只能返回如下几个结果:

number,boolean,string,function(函数),object(NULL,数组,对象),undefined

所以这玩意跟instanceof完全是两码事

在javascript中如果你需要调用一个函数, 需要在函数后使用调用运算符”()”.