万物皆函数
万物皆对象
函数是javascript里面的核心内容。
javascript的函数是最难理解的,同时混淆了太多的概念在里面。
javascript存在静态属性么?我觉得是否定的,但是有些书或资料上面经常出现这个字眼,我觉得有必要把自己的理解记录下来,以方便以后的理解。
静态属性,私有变量,私有属性;
私有变量是比较容易理解的,例如下面代码
var gloal="gloal";
function a(){
var self="self";
}
function b(){
console.log(gloal)
}
a();
selft在函数a的作用域里面,外面无法访问,可以理解为函数a的私有变量
相对私有变量,gloal可以理解为全局变量
但是这里无法通过a.self,或者实例后new a().self,a只能理解为某个作用域内的临时变量,存在栈内存里面
这里的self(私有变量)不能和“私有属性”混淆。
私有属性是指针对实例而言,只能实例后调用,占多份内存
prototype是实例共享的,修改任何一个实例的prototype都会影响到其他实例的对应 prototype
而静态属性只占一份内存,可以不实例直接调用也可以实例后调用(虽然调用的是同一个内存的东西),javascript没有提供这个功能,虽然看起来形式上可以直接调用,实际上是个实例追加一个"实例方法",例子看代码A,B,Function,String,Number,Array这些类型的都是Object对象的实例([] instanceof Object 返回的是true可以证明这点,虽然一开始我就知道,但是从来没有正视过这个问题)
下面代码注析/**/之间代码为一个功能点,//为单独功能点,
function F() {
b = 100;
this.self = "self";
console.log("构造函数内的F",F)
F.a="aa";
return this;
}
F.b = 200;
b = 300;
self = "window"
F.prototype.getb = function () {
console.log(this.b);
};
//添加F的private属性,及时是F的实例也无法访问,而不是理解为static属性,添加到了F函数实例上了,属于函数的实例属性,代码A
F.add = function () {
console.log("hehe")
}
console.log(F.add);
console.log("hasOwnProperty",F.hasOwnProperty("add"));//确定add是保存在F的构造函数上面
// console.log(new F().add())
// new F().getb();//undefined,F函数体内没有加this.b,所有没有自己的b
// console.log(b)//100,F函数体内没有加this.b修改的还是全局范围内的b
// console.log("F.self:", F.self) //undefined,F没有执行,F查找的是Function对象
/*
console.log("F().self:", F().self) //self,如果F没有返回this,就报错TypeError: Cannot read property 'self' of undefined
console.log("self", self) //undefined,因为F函数体内的self加了this所以上面F()的执行不会影响全局的self
*/
// console.log("new F().self", new F().self)//self
// F.getb() //undefined,F可以理解是function对象的一个实例,但是同时他有承担构造函数的功能
//javascript中的函数不是一个原始值,而是一种特殊的对象!!!!!!这个真的很特殊,承担了javascript整个核心内容
//这个概念比java的类还要复杂,因为他承担了太多的功能同时混淆太多的概念在里面
//犀牛书(第六版)P180对这个有详细的概述,
/*
//代码块
console.log("F.prototype",F.prototype)
console.log(F.add);
*/
/*
//代码块
console.log("F.a:",F.a);//因为没有()执行,所有构造函数是不会执行的也就没有a属性
console.log(new F())
console.log("F.a:", F.a);//“aa” 应为执行了,所有给F添加了a私有属性属性
console.log("new F()再次实例",new F())// {self: "self"},F.a为私有属性,不会被实例、
*/
/*
var a=new F();
a.add="100";//这个代码和F.add是一样的,代码B
console.log("实例后的a添加私有属性或者理解是实例属性",a);
*/
/*
//代码块
//区分new 之后 和不new的区别
console.log(typeof new F())//Object,可以等同和function是同等类型对象
console.log(typeof F)// function
*/
// console.log(F.getb)//undefined
//console.log(new F().add())//Uncaught TypeError: (intermediate value).add is not a function
// var newF=new new F(); //text.html:70 Uncaught TypeError: (intermediate value) is not a constructor,代码C
上面代码中所谓的私有属性的添加形式有两种:
一种是在构造函数里面给F添加的a属性,
一种是在构造函数之外给F添加的add属性
其实他们都是Function实例F的实例属性或者说是私有属性,不能被F的实例继承
它不存在F的实例的构造函数上面,也不存在F实例的原型链上面(原型链肯定是没有的,构造函数上没有?可以质疑.)。
这时候问题来了,F既然是Function的实例,为什么还可以继续new一个实例,
在js中实例是不可以继续new的,这个是个常识,因为它已经实例了不再是个构造函数(代码C),
这个就是js function的灵(蛋)活(疼)的地方,function是一个特殊的对象!!!
function F(){
b=100;
console.log(this)
//return this;
this.self="self";
}
F.b=200;
b=300;
F.getb=function(){
console.log(this.b);
};
// F.prototype.getb = function () {
// console.log(this.b);
// };
//F.getb() //200
//F().getb(); //index.html:46 Uncaught TypeError: F(...).getb is not a function
//new F().getb();//index.html:46 Uncaught TypeError: F(...).getb is not a function,构造函数自身属性只能在构造函数体内添加。。,prototype可以在体外添加
//console.log("a.self:",a.self)
//new F.getb(); //undefined F.getb为构造函数,所以F.getb的b为undefined
//new new F().getb(); //(intermediate value).getb is not a constructor