ECMAScript: 规定js的语法规范
DOM:Document Object Model 给我们提供了一套完整的操作页面元素的api application programming interface
BOM: Browser Object Model window.open() Navigator window.navigator.userAgent
2.Delete关键字 delete关键字可以用来删除 对象的属性 未使用var声明的变量
var doggie = { name: '旺仔', age: '5 months', gender: 'male', breed: '博美', color: 'white' } console.log(doggie.name); // 旺仔 // delete关键字有返回值,用来表示删除是否成功 // 如果删除的是不存在的属性,返回值为true // 如果删除的是原型中存在的属性,返回值也为true,但是并未删除 var result = delete doggie.name; console.log(doggie.name, result); //undefined true var alaska = 'haha'; teddy = '天 地 空气'; var resultA = delete alaska; var resultT = delete teddy; console.log(resultA);//false console.log(resultT);//true3.定义函数的三种方式
// 三种定义函数的方式主要区别是:变量提升。 //1.函数声明 function funcName(){ //函数体 } //2.函数表达式 //在使用函数表达式声明函数的时候,function后面可以跟函数名 //但是 这个函数名。只限在函数内部使用,外部无法访问。递归的时候用的比较多 var funcName1 = function name(){ console.log("i have two dogs"); } funcName1(); // 递归:函数内部使用函数名 var func = function fibNaci(n){ if (n<=2) { return 1; } return fibNaci(n-1)+fibNaci(n-2); } console.log(func(5)); //3.Function var funcName2 = new Function();4.异常捕获, try catch finally 异常处理 try{ //可能出现异常的代码 } catch(e){ //e 异常对象 包含异常信息 //出现异常后的处理代码 } finally{ //无论是否发生异常 都会执行的代码 //一般情况下是做资源释放的操作 } throw
5.面向对象编程的准则:DRY Don’t Repeat Yourself
可以选择使用函数进行封装,但是缺点是: 1).函数太多的时候,会污染全局变量 2 ) .代码结构不清晰,维护起来不方便
也可以使用对象进行封装,优点是: 1)使用对象将代码进行功能模块的划分,有利于日后的维护
6.面向对象的三大特性 *封装
*继承 自己没有的,拿别人过来用,就是继承 var obj = { }; var obj1 = { name : "张学友", sayHello: function () { console.log("你好,我是张学友"); } } //混入式继承(mix-in) for in for(var k in obj1){ //k可以获取到对象的每一个属性 //obj1[k]可以获取到对象的每一个属性的值 //这里使用k给对象新增属性的时候,不可以使用点语法 obj[k] = obj1[k]; } obj.sayHello();*多态 父类引用指向子类的对象(JavaScript中用不到)
7.创建对象的方式
//1.对象字面量 {key:value,key:value...} //只能创建一次对象,复用性较差,如果要创建多个对象,代码冗余度太高 var doggie = { name: '旺仔', age: '5 months', gender: 'male', breed: '博美', color: 'white' } console.log(doggie.gender);//调用 //2.使用内置构造函数 var littleDog = new Object(); littleDog.name = "旺仔"; littleDog.friends = "豆豆"; littleDog.habbit = function() { console.log("跟踪美女~~~"); } littleDog.habbit(); //调用 //3.封装简单的工厂函数 (不推荐使用了) function myLittleDog(name, friends, habbit) { var dog = new Object(); dog.name = name; dog.friends = friends; dog.habbit = habbit; return dog; } var puppy = myLittleDog("旺仔","豆豆",function() { console.log("跟踪美女~~~"); } );//实例化 puppy.habbit();//调用 //4.自定义构造函数 //构造函数其实也是函数,但是通常用来初始化对象 //构造函数是用来初始化对象的(给对象新增成员) //构造函数名,首字母要大写!!!以示区分 function Person() { //默认隐含的操作,把刚才用new新创建出来的对象赋值给this this.name = "尼古拉斯凯奇"; this.age = 50; this.sayHello = function() { console.log("Hey man"); } //构造函数的返回值 //1).如果不写返回值,默认返回的是新创建出来的对象 (一般都不会去写这个return语句) //2).如果我们自己写return语句 return的是空值(return;),或者是基本类型的值或者null,都会默认返回新创建出来的对象 //3).如果返回的是object类型的值,将不会返回刚才新创建的对象,取而代之的是return后面的值 return null; } //new 是用来创建对象的,必须要写的,如果不加,Person就不会当成构造函数调用,而只是一个普通的函数,那么函数中的this指的是window,属性都加到window上了,通过打印console.log(window.age)就知道了。 var p = new Person(); //new Object(); 通过构造函数创建对象的过程 就叫做实例化 console.log(p); p.sayHello(); ps: //注意:如果像使用正常的函数一样使用构造函数 //构造函数中的this将不再指向新创建出来的对象(因为根本就没有创建对象) //构造函数中的this这个时候指向的就是window全局对象 //当使用this给对象添加成员的时候,全部都添加到了window上 Animal("旺仔","博美",function () { console.log("我是函数"); }); //这是一个错误的演示! But, //使用这种方式存在的问题 //1.全局变量增多,造成污染 //2.代码结构混乱,不易维护 是不是很耳熟,往上翻翻看,~_~ 另外,再看下另外一个问题: function studyMethod() { //使用这种方式写好的方法中的this指向的就是调用该方法的对象 //this 谁调用就是谁 console.log("我叫" + this.name + "Good Good Study Day Day Up"); } function Student(stuName) { this.name = stuName; //如果在构造函数中定义函数,那么每次创建对象,都会重新创建该函数 //但是函数内部代码完全相同,就造成了资源浪费 //为了处理这个问题,我们要让所有的对象共用一个方法 // this.study = function(){ // console.log('stu 和 stu1造成了资源浪费'); // } //在构造函数外部定义好该函数,将该函数赋值给构造函数内的方法 this.study = studyMethod; } //如果构造函数没有参数,那么在调用的时候 小括号 可以省略 var stu = new Student("旺仔"); stu.study(); var stu1 = new Student("豆豆"); stu1.study(); 注意:函数内部的study方法,我把第一种屏蔽了,为什么呢? stu 存放的内存地址 --> 0XEA0211 name:"旺仔" stu1存放的内存地址 --> 0XBE0267 name:"豆豆" 如果用第一种方式: 每次创建一个对象,会开辟一块内存来放function(){ console.log('stu 和 stu1造成了资源浪费'); },所以就造成了不必要的浪费,用第二种方式,只用开辟一块儿内存空间比如说0x111111,每次创建stu或者stu1,stu2...的时候,都有一个study变量存放的是0x111111。这样也符合面向对象的思想。 //5.原型模式(一般只把方法绑定到原型上,属性一般写在构造函数中) function Person(name, age, gender) { this.name = name; this.age = age; this.gender = gender; // this.say = sayHello; } var p = new Person("张学友", 18, "male"); var p1 = new Person("刘德华", 19, "male"); Person.prototype.sayHello = function() { console.log("你好我是" + this.name); } Person.prototype["sing"] = function() { console.log("一千个伤心的母牛"); } p.sayHello(); p1.sayHello(); p.sing(); p1.sing(); //如何使用原型来解决构造函数存在的问题? //构造函数的原型对象中的成员,可以被该构造函数创建出来的所有对象访问 //而且,所有的对象共享该对象 //所以,我们可以将构造函数中需要创建的函数,放到原型对象中存储 //这样就解决 全局变量污染的问题 以及 代码结构混乱的问题 //6.组合使用构造函数和原型模式 //7.动态原型模式 //8.寄生构造函数模式 //9.稳妥构造函数模式 创建对象先说这么多吧,后几种有机会再扩展。8.原型的概念以及使用方法
自定义构造函数Person function Person(name, status) { this.name = name; this.status = status; this.act = function () { console.log("演戏"); }; this.exercise = function () { console.log("就不强身健体,就要保卫祖国"); } } //实例化 var p = new Person("xyz","single"); // p.exercise(); //原型是什么? //1.在构造函数创建出来的时候,系统会默认的帮构造函数创建并关联一个神秘的对象,这个对象就是原型 //2.原型默认的是一个空的对象 //原型的作用 //3.原型中的属性和方法,可以被使用该构造函数创建出来的对象使用 //4.如何访问构造函数的原型 // 构造函数.prototype console.log(Person.prototype); console.log(p.prototype); //访问不到 //要这样才对:p.__proto__ //5.注意 prototype是构造函数的属性,跟对象没有关系 //6.如何给原型对象添加属性和方法? //使用对象的动态特性 Person.prototype.exercise = function () { console.log("强身健体,保卫祖国"); } p.exercise(); //7.当使用对象去访问属性和方法的时候 //1).会首先在对象自己内部进行查找,如果找到了,就直接使用 //2).如果没有找到,就去原型中查找,查找到之后,使用 //3).如果原型中还没有, 如果是属性,就是Undefined //如果是方法,就报错 // p.sing(); //本身和原型中都没有 就报错 知道了原型是什么之后,那么我们一般会怎么使用原型呢? //1).利用对象的动态特性给原型对象添加成员(属性和方法) //2).直接替换原型对象 第一条已经使用了,我们看第二条: //如果使用第二种方式使用原型,那么会出现如下问题: //在替换原型之前创建的对象的原型 和 在替换原型对象之后的创建的对象 //的原型 不是同一个! function Person(name, age, gender) { this.name = name; this.age = age; this.gender = gender; } // ------------------- Person.prototype.sayHello = function() { console.log("Nice to meet you all"); } // ------------------- var p = new Person("旺仔", 5, "male"); p.sayHello(); // ------------------- //替换了原型对象 Person.prototype = { msg: "你猜我在不在" }; // ------------------- var p1 = new Person("doudou", 7, "male"); console.log('---------'); console.log(p.msg);//不能:undefined console.log(p1.msg);//能: 你猜我在不在 p.sayHello(); //能:Nice to meet you all p1.sayHello(); //不能: 报错 p1.sayHello is not a function //使用原型的注意事项 //1.使用对象访问属性的时候,如果在本身内找不到就会去原型中查找 //但是使用点语法进行属性赋值的时候,并不会去原型中进行查找 //使用点语法赋值的时候如果,对象中不存在该属性,就会给该对象新增该属性,而不会去修改原型中的属性 //2.如果在原型中的属性是引用类型的属性, //那么所有的对象共享该属性,并且一个对象修改了该引用类型属性中的成员,其他对象也都会受影响 //3.一般情况下不会将属性放到原型对象中 //一般情况下原型中只会放需要共享的方法 ---------- constructor的知识点: function Person(){ } console.log(Person.prototype.constructor); Person.prototype = { constructor : Person }; console.log(Person.prototype.constructor); //在使用新的对象替换掉默认的原型对象之后 //原型对象中的constructor属性会变成 Object //为了保证整个 构造函数---原型----对象 之间的关系的合理性 //应做如下操作: //在替换原型对象的时候,在新的原型对象中手动添加 constructor属性