comsole.time("text")//计时器text计时器的名字开始计时,放在程序开头需要一个字符串参数(text)作为计时器的标识
comsole.timeEnd("text");//停止计时器
对象
么有对象怎么办呢给自己new一个
js中基本数据类型有:
String 字符串
Number数值
Boolean 布尔值
Null 空值
Undefined未定义
object也是js数据类型只要不是上面五种都叫对象
基本类型的不足,都是单一的值,值和值之间没有联系
对象属于复合的数据类型,在对象中可以保存多个不同数据类型的属性(类似c语言的结构体)
对象的分类
1.内建对象
由ES标准中定义的对象,在任何ES实现中都可以使用
比如:Math String Number Boolean Function Obiect.....
2.宿主对象
由js运行环境提供的对象,目前主要指浏览器提供的对象
比如 BOM(浏览器对象模型) DOM(文档对象模型)
这是两组对象,他们两里面都有一堆对象
比如常用的,这两个都是由浏览器提供的,不用自己创建
console .log();
document.write();
3.自定义对象:
由开发人员自己创建的(最难的)
对象的基本操作:
创建对象
使用new关键字调用的函数是构造函数,是构造函数constructor,构造函数是专门创建对象的函数
var obj =new Object();//构造一个对象new一个新的,对象是通过Object();函数创建的.
(单生狗们有救啦,没有对象的自己new一个)
new好了等于拿到盒子了,在对象中保存的值叫属性
对象像一个塑料袋可以装不同的东西
向对象添加属性
语法:对象.属性名=属性值;
var obj = new Object
obj.name="刘聪慧";
obj.age="18";
obj.xingge="是小狗";
console.log(obj)
读取对象中的属性:
语法:对象.属性名;
如果读取没有保存的属性不会报错,会返回undefined
修改属性值:
语法: 对象.属性名 = 新值;
删除对象的属性值
语法: delete 对象.属性
delete obj.name;//删除属性值
对象的属性名不用遵守标识符的规范,想怎么起怎么起,但是我们还是尽量按照标识符规范来做
如果使用特殊的属性名不能采用.的方式来操作,(比如用标识符来当属性名),需要另一种方式
语法:对象["属性名"] = 属性值,读取时也要采用这种方式
在[]中可以直接传递变量,变量值是多少就会读取哪个属性
obj["123"] = 789;
//传123可以读取789
var n = "nihao;
//用[]传n可以读取nihao"
js对象的属性值
可以是任意的数据类型,也可以是一个对象,也可以是函数
但是调用对象中的函数也叫调用对象的方法
var obj = new Object;
obj.syaname = function fun(){
console.log(obj.name)
};
obj.sayname();//调用方法
fun(); //调用函数
可以用in运算符检查一个对象中是否含有指定的属性
如果有返回true 没有返回false
语法:
"属性名" in 对象
基本数据类型:保存的值
引用数据类型:保存的是地址
保存在栈内存中 ,值与值独立存在
对象保存在堆内存里每创建一新对象都在堆里开辟一个空间
而变量保存的是对象在堆内存的地址(保存的是对象的引),当一变量修改i属性时其他的变量属性也会改
当比较两个基本数据类型的值,就是比较值,比较两个引用数据类型时比较的是引用数据的的地址
对象字面量:
使用对象字面量来创建一个对象
var obj = {}; 与var obj = new objiect是一样的创建对象
对象字面量可以加""也可以不加,建议不加,特殊属性名一定要加""
属性名和属性值是一组一组对称结构,名和值之间使用,多个名值之间用,隔开,后面没有属性就不用加,
语法:(属性:属性值.属性名:属性值;....)
var obj ={name= "猪八戒"}//创建对象同时指定属性
函数的简介
函数也是一个对象
和普通对象的区别:函数可以封装功能和代码,保存一些代码在需要时候调用
创建函数对象
可以对封装的代码以字符串的形式传递给构造函数
var fun =new Function();
封装到函数中的代码不会立即执行,只会在调用时执行
调用函数:函数对象();
调用函数时函数中封装的代码会按照顺序执行
使用函数声明创建函数
语法:
function 函数名( [形参一,形参二....]){
语句...(函数体)
}
function fun2(){
console.log("这是一个函数")
}
函数表达式创建一个函数
var 函数名 = function (){ //把匿名函数赋值给创建变量
语句....
};
函数的参数:
定义求和函数
function sum(a,b){ //多个形参用逗号隔开
var a ;
var b 1;//声明并不赋值
console. log(a+b)
}
//在调用时可以指定实参
注意:
调用函数解析器不会检查实参的类型.所有要注意,是否有可以收到非法实参,如果非法应该进行类型转换
调用函数解析器不会检查实参的数量多余的实参不会被赋值,如果实参少于形参会返回 undefined
函数值返回值
return
使用return返回,在函数中return后的语句不会再执行了有像break,如果return的语句不跟任何值就相当于返回一个undefined,如果函数中没有return返回的也是undefined,return可以返回任意类型的值
function sum(a,b){
var a ;
var b ;//声明并不赋值
var d = a + b;
return d;//返回结果不做操作
}
,定义一个函数判断数字是否是偶数,是返回turn 不是就返回false
方法一:
function even(a){ //
var a ;
if(a%2==0){
return true;
}//声明并不赋值
else{
return false;
}
console.log("return = "+return);
方法二:
function even(a){ //
return a % 2 == 0 ;
}
定义一个函数根据半径计算面积
function round(r){ //多个形参用逗号隔开
var r ;
var area;
area = 3.14*r*r
return area;
//声明并不赋值
}
area =round(5);
console.log("area="+area);
实参可以是对象.也可以是函数(函数调用函数叫递归)
fun(even(10));相当于实参传递的是even中的返回值
fun(even);传参的函数对象,相当于直接使用函数对象
返回值类型
break 退出当前循环 continue 跳过当此循环,return 直接退出函数
返回值可以是对象可以是函数,函数内部还可以声明函数
function xinxi(){
var obj = new Object
obj.name = "孙悟空"
obj.age = "5000"
obj.adress ="花果山"
return obj;
//声明并不赋值
}
var a =xinxi();
console.log("名字="+a.name);
立即执行函数的
函数定义完立即被调用,往往只会执行一次
用括号圈起匿名函数表示一个整体
(function(){
alert("这是一个立即执行的函数");
})();
对象
枚举对象中的属性
使用for...in语句找出一个对象中所有属性
语法:
for (var 变量 in 对象) {
}
有几个属性for循环体就执行几次
每次执行都会将对象中的一个属性名字赋值给变量
for (var in obj){
console.log("属性名"+n);
console.log("属性值"+obj.[n]);
}
作用域
一个变量的作用范围
全局作用域
编写在script标签中的js代码,都叫全局作用域,页面打开时创建,关闭时销毁
全局作用域有个全局对象windos 它代表的是一个浏览器窗口.它由浏览器传创建我们剋有直接使用
在全局作用域中,创建的变量都会作为windos对象的属性来保存
函数会作为windos的方法来保存
变量声明提前
使用var关键字声明变量.会在所有代码执行之前声明,但是不会赋值.如果声明变量不用var
则变量不会提前声明
函数声明提前
使用函数声明形式创建的函数 function 函数(){
}
它会在所有代码执行之前就被创建
使用函数表达式的形式不会被提前创建
var fun = function(){
}
var= fun 会提前创建但是不会对fun进行赋值
函数的作用域(局部的)
调用函数时调用函数时创建函数作用域,函数执行完毕后,函数作用域销毁
每调用一次,创建一次作用域,他们之间是相互独立的
在函数中可以访问全局的变量,但是全局作用域中无法访问函数中变量
当在函数作用域中运用变量时,会优先在函数体中寻找变量,如果当前函数体中没有,就像上一级寻找,如果全局作用域没有,就会报错
在函数作用域声明通提前函数体内声明变量不用var 会把函数体中的局部变量变成全局变量
debug
如何让代码运行停下,利用断点调试代码执行流程
this
解析器在调用函数时每次都会像函数内部传递一个隐含的参数,这个隐含的参数就是this ,this指向的是一个对象,这个对象我们称之为函数上下文对象,根据函数调用的不同,this指向不同的对象
1.以函数的形势调用时,this 永远都是windos
2 以方法的形式调用时,this就是方法调用的那个对象
谁调用this就是谁代码示例
var name = "全局";
function fun(){
console.log(this.name)
}
var obj {
name:"孙悟空",
sayname:fun
};
var obj2 {
name:"沙和尚",
sayname:fun
};
obj.name();//根据调用者不同显示不同的值
使用工厂方法进行创建对象
通过该方法大量创建对象
function createParson(){//利用函数批量创建对象
var obj = new Object();
//向对象中添加属性
obj.name= "孙悟空";//不可以将属性值写死
obj.age ="18";
obj.sayName = functio(){
alert(this.name);
}
return obj;//将新的对象返回
}
var obj2 = creatPerson();
console.log(obj2);
改进
function createParson(name, age){//利用函数批量创建对象
var obj = new Object();
//向对象中添加属性
obj.name= name;//不可以将属性值写死,利用传参给对象的属性赋值
obj.age = age;
obj.sayName = function(){
alert(this.name);
};
return obj;//将新的对象返回
}
var obj1 = creatPerson("猪八戒",56);
obj1.sayName();
console.log(obj1);
//调用obj1 中的function中的方法弹窗输出当前对象的名字
//函数的调用
创建狗
function createdog(name,age){
var obj =new Object();
obj .name=name;
obj .age=age;
obj .sayHell = function(){
alert(this.sayHell);
};
return obj;
}
var dog = createdog("旺财",3);
console.log(dog);
alert(dog);
构造函数
例子
function Person(name,age){
this .name=name;
this .age=age;
this .sayHell = function(){
alert(this.sayHell);
};
}
var per = new Person("小朋友",3);
var per2 = new Person("莉莉",8);//不加new就是普通,加new就是构造函数
console.log(per);//使用同一个构造函数就是同一个类
首字母大写跟普通函数没区别,构造函数用对象来调用
流程1
立刻创建一个新建的对象
将新建对象设置为函数中的this,this就是新疆的对象,this来引用
逐行执行函数中代码
,将新建对象作为返回值返回
使用一个构造函数创建的对象我们称为一类对象,也将这个构造函数称为一个类
通过构造函数创建的对象我们叫实例,
可以使用instanceof检查一个对象是否为一个类的实例
语法:
对象 instanceof 构造函数
如果是返回true 如果不是返回false
console.log(per instanceof Person);
this的三种情况:
1函数形式调用时,this是windos
2方法形式调用时,谁调用方法this就是谁
3以构造函数调用时this就是新创建的那个对象
创建一个person构造函数,为每一个对象都添加了sayName方法目前我们方法是在函数内部创建的,就是构造函数每执行一次就会创建一个新的sayName方法也就是所有实例sayName都是唯一的,这就导致构造函数执行一次就创建一个新的方法,执行多少次就会创建多少方法而这些方法都是一样的,这完全没必要,完全可以使所有对象共享同一个方法
可以将Person中sayName在全局中定义
污染了全局作用一的命名空间,一个项目往往有很多人去做
而且定义在全局作用域不安全
function Parson(name, age){//利用函数批量创建对象
this.name= name;//不可以将属性值写死,利用传参给对象的属性赋值
this.age = age;//构造函数
this.sayName = fun()
}
//将sayName方法定义在全局中
funcrion fun() = {
alert("哈喽,我是"+this.name)
}
var per = new Person("孙悟空",18);
var per = new Person("孙悟空",18);
//虽然这种方法解决了每调用一次函数生成一个方法的浪费
//但是也不怎么安全
原型 prototype
我们每创建一个函数解析器(浏览器)都会向函数的属性中添加一个prototype
function Person()
{ }
console .log(Person.prototype)//原型这个属性是对象
//输出(objiec Object)
这个属性对应着一个对象我们称为原型对象
Myclass函数对象|
prototype | 0X123 ---------->原型对象(0X123)
通过Myclass创建的对象mc /
隐含属性 | 0X23 /指向相同的 原型对象(0X23)
如果函数作为普通函数调用prototype没有任何作用
当函数以构造函数方式调用时,它所创建的对象都有一个隐含是属性
指向该构造函数的原型对象,我们可以_proto_来访问该属性
function Myclass()
{ }
var mc = new Myclass();
console .log(mc._proto_)
原型对象相当于一个公共区域,所有同一个类的实例,都可以访问到这个原型对象,我们可以将这个类的公有部分设置到它的原型对象中
当我们访问对象的一个属性或者方法时,他会先在自身寻找,如果有直接使用,如果没有就会去原型对象中寻找,如果找到直接使用
以后我们创建构造函数时,可以将这些对象共有的类,统一添加到构造函数的原型对象中,这些就不用分别为为每一个对象添加,也不会影响全局作用域,就可以使每个对象都有这些属性和方法了
向Person对象原型中添加一个sayName方法
function Parson(name, age){//利用函数批量创建对象
this.name= name;//不可以将属性值写死,利用传参给对象的属性赋值
this.age = age;//构造函数
this.sayName = sayName();
}
Person.prototype.sayName =function(){
alert("哈喽,我是"+this.name);
};
var per1 = new Person("孙悟空",18);
var per2 = new Person("猪八戒",18);
per1.sayName();
per2.sayName();
在原型中添加name属性
function Myclass(){
}
Myclass.prototype.name = "我是原型中的名字";//在原型中定义了名字属性
var mc = new Myclass();
console.log(mc.name);
in
可以使用in检查对象中是否含有某个属性,有的话返回true,没有返回false,如果对象中没有,而原型中有这个属性也会返回true
语法:
"属性名"in 对象
conlose.log("name"in mc)
hasOwnProperty()函数
可以使用这个函数检查对象自身是否有某种属性,只有对象本身有这个属性才会返回true
console.log(mc.hasOwnProperty("age"));
原型对象也是对象他也有原型,当我们使用一个对象的属性或者方法时,会先在自身中寻找:
如果自身中有则直接使用
如果自身没有则去原型对象中找.如果原型对象中有,则使用
如果原型对象没有则去原型对象的原型中找.直到找到Object对象的原型
Object对象的原型没有原型,如果在Object对象没有找到就返回undefined
console .log(mc._proto_._proto_._proto_);
当我们在页面中打印一个对象时,事件上时输出的对对象tosSring()方法的返回值
console .log(per.toString());
function Parson(name,age){
this.name=name;
this.age = age;
}
var per = new Person("猪八戒",18);
var result = per.toString();
var result
var result = mc.toString();
console.log("result="+result);//输出结果为[object Object]
console.log(mc.__proto__.__proto__.hasOwnProperty("toString"));
//输出结果为true 说明则个toString在原型的原型object中
如果我们希望在输出对象时不输出object ,可以在原型中添加一个toString方法
function Myclass( xuehao ,age ){
this.xuehao =xuehao;
this.age =age;
}
//修改原型的toString
Myclass.prototype.toString= function(){
return "Myclass[xuehao="+this.xuehao+",age="+this.age+"]";
}
var mc = new Myclass(2265,18);
var mc1 = new Myclass(2268,17);
var result = mc.toString();
console.log(mc);
垃圾回收(GC)
就像人生活的时间长了会产生垃圾-一样, 程序运行过程中也会产生垃圾
这些垃圾积攒过多以后,会导致程序运行的速度过慢,
所以我们需要一个垃圾回收的机制,来处理程序运行过程中产生垃圾
一当一个对象没有任何的变量或属性对它进行引用。此时我们将永远无法操作该对象。此时这种对象就是一个垃圾, 这种对象过多会占用大量的内存空间。导致程序运行变慢,所以这种垃圾必须进行清理。
在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,
我们不需要也不能进行垃圾回收的操作
.我们需要做的只是要将不再使用的对象设置null即可
var obj = new Object();
obj =null;