1.数据,变量和内存
1.数据,变量和内存
- 什么是数据?
存储在内存中表示特定信息的东西,本质是0101;
数据的特点:可传递,可运算,一切且数据
所有内存操作的目标:数据
- 什么是内存?
内存条通电后产生的可存储数据的空间(临时的)
内存条的产生和死亡:内存条(电路板)->通电->产生内存空间->存储数据->处理数据->断电->内存空间和数据都消失
一块小内存存储的两个数据:地址值和内存存储的数据
- 内存的分类:
栈->存储全局变量和局部变量
堆->存储对象
- 什么是变量?
可变化的量,由变量名和变量值组成;
每个变量对应一个小内存,变量名对应内存中的地址值,可以通过变量名来找到内存,变量值对象内存中保存的数据;
- 内存,数据,变量之间的关系?
内存是用来存储数据的空间; 变量名是内存的标识; 注意:变量之间的赋值是值传递,而创建对象时发生的是地址传递;
JS引擎如何管理内存:
(1.)内存的生命周期:
分配小内存空间,得到它的使用权;
存储数据,可以反复进行操作;
释放小内存空间;
(2.)释放内存:
局部变量:函数执行完后自动释放;
对象:成为垃圾对象(没有变量指向它)->由垃圾回收器自动回收
2.对象
对象是什么?
保存多种数据的容器;有利于管理多个数据
对象的组成?
属性:属性名(字符串)和属性值组成,一般自己写的时候不用把属性名写成字符串;
方法:一种特殊的属性(特指函数)
访问对象数据的方法?
(1.)用对象.属性名来访问
(2.)用对象['属性名']或者对象[变量名]来访问(用于特殊情况,比如属性名是关键字或者想用变量时)
3.函数
函数也是对象,只不过保存的数据是代码,函数不能添加自己的属性或者方法,只能设置this的属性或者方法给它的实例对象使用;
创建函数的方法有三种:a.声明式 function xxx(){} b.赋值式 var xxx=function(){} c.调用构造函数 var xxx=new function() 回调函数的定义:a.自己定义的 b.自己没有调用 c.函数最终执行了
常见的回调函数有:a.dom事件回调函数 b.定时器回调函数 c.ajax请求回调函数 d.生命周期回调函数 IIFE:即匿名函数自调用,(function(){})()这种形式.最外层加上括号是为了把这个函数看成一个整体,优点是隐藏实现,不污染全局环境;
这里需要注意:JS必须加;的地方有两个,一个是小括号开头的语句前面要加分号,第二是中方括号开头的语句前面加分号;IIFE是第一种
关于函数中的this:
任何函数本质上都是通过某个对象来调用来(new一个实例对象也算是调用了函数,创建对象时就调用了构造函数,这时的this是那个实例对象)
所有函数内部都有一个this,它的值是调用函数的当前对象
(在这里我的理解是,只能是实例对象来调用函数,缺了明确的对象调用外,都是window对象来调用的函数,如果在全局声明一个函数,那么就相当于与给window对象添加了一个方法属性;)
<body>
<!--
1. this是什么?
- 任何函数本质上都是通过某个对象来调用的,没有直接指定就是window对象
- 所有函数内部都有一个变量this
- 它的值是调用函数的当前对象
2. 如何确定this的值?
- test():window
- p.test():p
- new test():新创建的对象
- p.call(obj):obj
-->
<script type="text/javascript">
function Person(color) {
console.log(this)
this.color = color;
this.getColor = function () {
console.log(this)
return this.color;
};
this.setColor = function (color) {
console.log(this)
this.color = color;
};
}
Person("red"); //this是谁? window
var p = new Person("yello"); //this是谁? p
p.getColor(); //this是谁? p
var obj = {};
p.setColor.call(obj, "black"); //this是谁? obj
var test = p.setColor;
test(); //this是谁? window
function fun1() {
function fun2() {
console.log(this);
}
fun2(); //this是谁? window
}
fun1();
</script>
</body>
4.原型链
每个函数都有prototype属性(保留的是地址值,显示原型),指向它的原型对象,默认是一个空的object空对象(但是一些特殊的,比如内部函数,会有设定好的object对象属性);
每个实例对象都有-proto-属性(地址值,隐式原型)指向他的原型对象;不能直接操作隐式原型(ES6之前),但能操作显示原型;
原型对象中有constructor指向实例对象的构造函数;
构造函数对象被创建时,自动添加prototype属性和原型的constructor属性,之后当创建函数的实例时,由prototype赋值给实例的-proto-属性; 原型链的别名是隐式原型链,可见这个链主要是靠对象的-proto-属性来传导的;
原型链是为了查找对象的属性
什么是原型:
原型:一个函数可以看成一个类,原型是所有类都是一个属性,原型的作用就是给这个类的一个对象都添加一个统一的方法。
什么是原型链:
每一个原型都有一个-proto-,它指向它的prototype原型对象;它的prototype原型对象又有一个-proto-,指向它的prototype原型对象,就这样层层向上直到最终找到顶级对象Object的prototype,这个查询路径就是原型链
- prototype:原型 | 显式原型
proto:原型链(链接点)|隐式原型
流程是:先在自身查找,找到返回|如果没有则沿着-proto-链找,找到后返回|如果还是没有,则返回undefined;
在原型链中,需要注意:所有函数都是Function的实例,包括它本身;object的原型对象不是对象类型,它的原型是空;
读取对象的属性时,会从该对象的原型链中寻找,如果是设置对象的属性值,不会查找原型链,而是直接添加此属性;
方法一般定义在原型上,属性一般通过构造函数定义在对象本身上;
关于Instanceof方法 A instanceof B 如果B函数的显示原型在A对象的原型链上,则返回True;把A看成实例对象走-proto-,B看成函数走prototype,B走一步,A随意走,如果能重合则返回true;
Object和Function的关系
结论:
- Function的__proto__指向自己的prototype:
Function.__proto__===Function.prototype
- Object原型的隐式原型为null:
Object.prototype.__proto__==null
- Object的__proto__指向Function的prototype:
Object的Object__proto__===Function.__proto__===Function.prototype
/*
* 对应名称
* - prototype:原型 | 显式原型
* - __proto__:原型链(链接点) | 隐式原型
* 从属关系
prototype -> 函数的一个属性:对象{}
__proto__ -> 对象Object的一个属性:对象{}
对象的__proto__保存着该对象的构造函数的prototype
*/
function Test(){}
console.log(Test.prototype);
const test = new Test()
console.log(test.__proto__);
console.log(Test.prototype===test.__proto__);//true
// 原型也是一个对象,也有__proto_-
console.log(Test.prototype.__proto__ === Object.prototype);//true
// 最顶层Object的原型的__proto__为null
console.log(Object.prototype.__proto__);//null
// Function和Object:既是函数也是对象
// Test是由Function构造出来的 const Test = new Function()
// 因此Test的__proto__指向Function的prototype
console.log(Test.__proto__===Function.prototype);//true
// 同样的道理 Function也是一个函数,也是被构造函数Function构造出来的 因此Function也应该有自己的__proto__和prototype
console.log(Function.__proto__);
console.log(Function.prototype);
console.log(Function.__proto__===Function.prototype);//true 所有Function的__proto__指向Function的prototype
const obj = {}
// obj是由new Object()而来的,const obj = new Object()
// Object也是一个Function
console.log(typeof Object);//function
// 因此 Object也是由Function构造而来的,const Object = new Function()
// 所以Object的__proto__指向Function的prototype
console.log(Object.__proto__===Function.prototype);//true
// 又因为Function.__proto__===Function.prototype,所以Object.__proto__===Function.__proto__
console.log(Object.__proto__===Function.__proto__);//true
Function与函数
Function是JavaScript提供的一种引用类型,通过Function类型创建Function对象。
在JavaScript中,函数也是以对象的形式存在的,每个函数都是一个Function对象。
//字面量方式创建函数
var fun =function () {
console.log(100)
};
//函数声明方式创建函数
function fn () {
console.log(200)
};
/* 创建Funtion类型的对象
* var 函数名 = new Function('参数',''函数体)*/
var f = new Function('a','console.log(a)');
f(2);//以函数方式调用