1.对象

在javascript里,一切都是对象,包括函数自身(不是指具体的函数,而是指"Function"这个东东)。
例如:

var fun1=new Function("num1","num2","alert(num1+num2)");

这时,fun1是一个函数的"实例",或者说函数对象,所以当然是一个对象。fun1.__proto__指向Function.prototype。
但同时,Function也有__prototype__:

所以,从这个则面可以看出,"Function"自己也是一个对象,它的__prototype__是创建"Function"的prototype,只不过是js引擎内核来实现,属于创世者的角色。
这个就有点像c#里的元数据一样,元数据定义了类,但元数据本身也可以用具体的类来体现(反射创建类的时候用得最多)
正因为javascript可以在语言本身和定义本身之间任意地切换,甚至很多情况下,语言本身和定义本身同为一体,在c#这类静态语言里,如果不通过反射这种“超维度”手段,你不能知道一个类定义了多少个成员。但js里,代码里可以用数组轻松遍历一个对象的所有属性,也可以自由地为对象添加成员,所以才被成为“动态语言”。

2.函数

一切的对象都能由函数创造,包括函数自身。
函数和对象是javascript世界里的两大核心。
函数可以作为一个普通的函数,例如:
var add=function(a,b){return a+b;}
也可以作为对象的构造函数,例如:

var Person=function(name,age){
this.name=name,
this.age=10;
this.selfIntro=function(){console.log("hi, i am "+this.name+", i am "+this.age+" years old")}
}
var tom=new Person("tom",10);
tom.selfIntro();

一个函数作为普通函数时和作为构造函数时,语法上面没有任何不同。甚至一个函数里即存在一段"普通函数"的代码,同时有有一段用于"构造对象"的代码。
但作为普通函数时和作为构造函数时,函数里的"this"的指向时不同的(在下边介绍)。

所以实际上,

var obj=new Object();
var str=new String("haha");
var birthday=new Date(2019,5,6);
var fun1=new Function("num1","num2","alert(num1+num2)");

以上这些对象,都是通过函数来构造的。这些函数就是Object,String,Date和Function。当然,这些函数自己又是一个对象。

3.原型:
在javascript里,每个函数对象都有一个原型(prototype)。这里说的"函数对象"是指使用typeof 命令显示出"function"的对象。如果 var obj={},因为obj只是一个对象,不是一个函数,所以obj.prototype是undefined。
但虽然非函数对象没有prototype属性,但任何一个对象都有__proto__属性,指向构造该对象的函数的prototype。(但__proto__不是语言标准里定义的东西,所以一些js环境里可能不支持)。

通过prototype,可以实现对象的继承。
在javascript中,调用一个对象的属性(包含方法)时,会先在对象自身寻找该属性。如果对象自身没有,则会在对象自身的__proto__上找,如果自身的__proto__没有,则会在自身__proto__对象的__proto__上找,一直找到尽头。

4.this:
javascript 的this 指向哪个对象,依赖于当前的上下文:

情况一:纯粹的函数调用,则this指向上层对象。

例如,

var fun=function(){console.log(this)};

这里的this指向window对象。类似地 <script>this</script>,this指向window,因为<script>标签里的执行上下文也是window。

而:

var a={x:1,m:function(){alert(this.x)}};

那么这时的this指向a这个对象。

情况二:作为构造函数调用时,this指向这个构造函数产生的新对象。

var Person=function(){this.name="tom";this.showName=function(){console.log(this.name)}};
var p1=new Person();
p1.showName();//tom

情况三:使用call或者apply 调用

通常,一个函数作为非构造函数的时候,this指向上级对象。有没有办法可以指定指向某个对象呢?答案是可以。方法是通过call()或apply:

var fun1=function(){this.name="tom"};

这时,如果执行fun1(),那么 fun1内部的this执行window对象,所以window.name=="tome"。
这是:

var obj={};
fun1.call(obj)

这时,fun1内部的this指向到obj这个对象。所以,obj.name=="tom"

btw: call和aplly的区别只是参数的形式不同而已。

最新文章

  1. CSharpGL(26)在opengl中实现控件布局/渲染文字
  2. 在使用 vscode 时 eslint 检测 .vue 文件中的less 部分内容
  3. php-fpm服务挂掉
  4. linux系统性能调优第一步——性能分析(vmstat)
  5. HDU 1018 大数(求N!的位数/相加)
  6. jquery商城类封装插件
  7. linux type 命令和Linux的五个查找命令
  8. Vacations
  9. 机器学习 - pycharm, pyspark, spark集成篇
  10. 对象Equals相等性比较的通用实现
  11. PHP中的面向对象OOP中的魔术方法
  12. java中计算两个时间差
  13. MySQL查看所有连接的客户端ip
  14. ES6系列之解构
  15. Mike and distribution CodeForces - 798D (贪心+思维)
  16. MVC 简介
  17. ie7/8浏览器报错:对象不支持&ldquo;trim&rdquo;属性或方法
  18. 高大上的JS工具
  19. 实验楼学习linux第一章第四节linux目录结构及文件基本操作
  20. 基于setTimeout制作滚动广告板

热门文章

  1. Java生鲜电商平台-会员积分系统的设计与架构
  2. 一款好用的SSH工具“FinalShell”
  3. 基于Morphia实现MongoDB按小时、按天聚合操作
  4. Spark(4)
  5. 在表单中使用ajax,成功后跳转指定页面 出现Provisional headers are shown 解决办法
  6. 01day-微信小程序 表单组件 动态绑定变量 导航组件 地图组件 view text button 上下滚动组件
  7. 使用hutool工具类进行导出
  8. 老男孩LINUX--打包压缩、查看、解压
  9. mysql字段约束-索引-外键---3
  10. mysql性能优化随笔