javascript 对象,函数,原型和 this
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的区别只是参数的形式不同而已。
javascript 对象,函数,原型和 this的更多相关文章
- 24 JavaScript对象访问器&JavaScript对象构造器
ES5引入了Getter和Setter Getter和Setter允许定义对象访问器 JavaScript Getter(get关键字):获取对象属性 <script> var perso ...
- JavaScript中两种类型的全局对象/函数
这里所说的JavaScript指浏览器环境中的包括宿主环境在内的. 第一种是ECMAScript Global Object,第二种是宿主环境(Host)下的全局对象/函数. 一.核心JavaScri ...
- 函数可以作为Javascript对象(哈希表)的键吗
一般Javascript书在讲解对象时,都指出Javascript中的对象可以作为哈希表,存储键值数据.通常情况下,键为字符串,如果键是数字的话,实际上在内部也会转换为字符串. 比如 var o = ...
- JavaScript之函数,词法分析,内置对象和方法
函数 函数定义 JavaScript中的函数和Python中的非常类似,只是定义方式有点区别. // 普通函数定义 function f1() { console.log("Hello wo ...
- JavaScript中两种类型的全局对象/函数【转】
Snandy Stop, thinking is the essence of progress. JavaScript中两种类型的全局对象/函数 这里所说的JavaScript指浏览器环境中的包括宿 ...
- javascript——对象的概念——函数 2 (内建函数与类型转换)
javascript 有许多内建函数,用于各种操作,以下为常用的内建方法. 1.parseInt(object,int):将输入的 int 进制的值 object 转换为 10 进制的数值: obje ...
- JavaScript对象this指向(普通键this指向 非指向函数的键)
1.结论 JavaScript对象普通键(非指向函数的键)this指向是window. 2.示例 <!DOCTYPE html> <html lang="zh"& ...
- JavaScript 没有函数重载&Arguments对象
对于学过Java的人来说.函数重载并非一个陌生的概念,可是javaScript中有函数重载么...接下来我们就进行測试 <script type="text/javascript&qu ...
- JavaScript教程——函数(arguments 对象)
arguments 对象 定义 由于 JavaScript 允许函数有不定数目的参数,所以需要一种机制,可以在函数体内部读取所有参数.这就是arguments对象的由来. arguments对象包含了 ...
- JavaScript对象,函数,作用域
JavaScript对象 在 JavaScript中,几乎所有的事物都是对象.JavaScript 对象是拥有属性和方法的数据. var car = {type:"Fiat", m ...
随机推荐
- Java面向对象——三大特性
Java面向对象——三大特性 摘要:本文主要介绍了面型对象的三大特性. 封装 什么是封装 封装,就是指一个类隐藏了对象的属性和实现细节,对自己的数据和方法进行访问权限控制,只允许某些类和对象进行访问和 ...
- MySQL基础(三)(操作数据表中的记录)
1.插入记录INSERT 命令:,expr:表达式 注意:如果给主键(自动编号的字段)赋值的话,可以赋值‘NULL’或‘DEFAULT’,主键的值仍会遵守默认的规则:如果省略列名的话,所有的字段必须一 ...
- JavaScript HTML DOM 节点
要向HTML DOM添加新元素,必须首先创建元素(元素节点),然后将其附加到现有元素. <!DOCTYPE html> <html> <meta charset=&quo ...
- 前端开发JS——引用类型
10.流程控制语句 注:var obj = {}:这里的obj转换boolean语句为true if语句和java是一样的,判断条件也是根据上篇博客提到的假性值 // 弹出一个带输入框的 ...
- 入职一个月后 对.net的感想
我本来应该找Java工程师的岗位的,因种种原因进入了.net开发工程师.然后,我进入了一扇新世界的大门. 1.语法不同,思想相同. 刚入职那几天,每天都好蒙,.net代码语法啥的都和Java不一样,a ...
- Red Hat安装虚拟带库
1.安装五个包 # yum -y install lzo-devel sg3_utils lsscsi mtx mt-st mtx源码:http://sourceforge.net/ 2.下载最新版的 ...
- nginx Linux内核参数的优化
默认的Linux内核参数考虑的是最通用的场景,这明显不符合用于支持高并发访问的Web服务器的定义,所以需要修改Linux内核参数,使得Nginx可以拥有更高的性能. 这里针对最通用的.使Nginx支持 ...
- 2-1Numpy概述
In [1]: import numpy as np In [2]: array=[1,2,3,4,5] array+1#没定义成numpy.ndarray类型是不能直接操作的 --------- ...
- Windows Server 2016-Hyper-V Replica副本功能介绍
Hyper-V副本是一种可用于复制虚拟机的功能,作为业务连续性解决方案的一部分.从Windows Server 2012中,Hyper-V角色引入了Hyper-V Replica作为虚拟机的内置复制机 ...
- pytest生成allure报告
在pytest框架中可以用很多插件来生成测试报告,本文总结下怎么生成allure报告 allure allure是一款开源的,专门用来展示测试结果的一个工具,allure可以与很多的测试框架做集成,比 ...