转载的~es5

JS面向对象(基础)

2016-12-21  本文已影响211人  空谷悠

一、面向过程和面向对象的区别、联系

1.面向过程编程:注重解决问题的步骤,分析问题需要的每一步,实现函数依次调用。

2.面向对象编程:注重问题中的对象,分析问题中对象的联系,实现对象间的通讯解决问题.面向对象编程淡化过程,强调对象 更贴近我们人日常处理问题的方式。

3.面向过程:所有功能都是在需要使用的时候才开发,相当于去餐馆点菜,现点现做,需要等。

4.面向对象:在正式开发之前,就先把所有需要使用的功能都开发好,并以属性或者方法的形式存放

在一个对象中,在实际开发的时候根据需要来调用写好的功能。相当于去快餐店吃快餐,菜都是

事先已经炒好的,去了就可以吃。


二、什么是对象?什么是面向对象?

1.对象是类的实例。对象是具体的事物。

2.只有对象才有属性和方法,基本数据类型没有,string等类型能够使用的方法来自他自身的构造器,在基本数据类型调用方法时会临时创建一个对象出来,在方法完成时自动销毁。

3.对象,黑盒子,是一个整体,对外提供一些操作,不了解内部的结构,知道表面的各种操作(按钮)。

4.面向对象简单的来说就是:不了解原理的情况下,会使用功能。面向对象是一种通用思想,并非只有编程中能用,任何事情都可以用。

5.面向对象编程也叫OOP,特点:①抽象,抓住核心问题,把最主要的、跟问题相关的特征抽出来。②封装:不考虑内部实现,只考虑功能使用。简单说:就是看不到里面的东西,用好表面的功能。③继承(遗传):从已有对象上,继承出新的对象。多重继承。多态。从父类上继承出一些方法、属性,子类,又有一些自己的特性。多重继承:可以同时继承多种父级的特性

6.对象的组成:①方法--函数:过程、动态的②属性--变量:状态、静态的。

7.变量和属性的不同:变量是自由的,不属于任何人。属性是有归属的,属于一个对象的。

//定义一个对象

//直接量

//var obj={};

//使用Object声明对象

var  obj= new   Object();

//覆盖式的定义方式,

var    person={

name:"张三",

age:"18",

hobby:function() {

console.log("我喜欢篮球");

}

}

//后面的会覆盖前面的

//var person = {

//name: "李四"

//}

//追加属性和方法

person.height="178cm";

console.log(person)

//调用

person.hobby();

console.log(person.name);

对象数组,一个数组里面有多个对象

var  phoneNumber=[{

name:"coco",

tel:"132432432"

}, {

name:"popo",

tel:"5840583"

}]

//取到里面的东西

//console.log(phoneNumber[0].name)

//如果数据比较多,需要用循环

for  (var  i=0; i<phoneNumber.length;i++){

console.log(phoneNumber[i].name);

}

var   person={

name:"张三",

height:"189cm"

}

//获取对象里面的东西,如果数据比较多,也可以循环

//key下标         value值

for(var  k   in   person) {

console.log(k);//对象的下标

console.log(person[k]);//获取单个值

}


三、工厂模式

并不常用,每次调用函数都重新定义了函数,(函数重复,资源浪费)

//工厂模式

function    factory(name,age) {//类

var   obj={};

obj.name=name;

obj.age=age;

obj.hobby=function() {

console.log("sing");

}

return     obj;

}

//直接调用

factory().hobby();//sing

//用参数接收调用

var     newFactory=factory("张三","18");//对象

newFactory.hobby();

console.log(newFactory.name);

//不用传参,用arguments,如果参数不确定的情况下,就用arguments

function   factory() {

//console.log(arguments);

var   obj={};

obj.name=arguments[0];

obj.age=arguments[1];

obj.hobby=function() {

console.log("sing");

}

return   obj;

}


四、构造函数

//创建构造函数,类似于类

function Student(name,sex){

//属性

this.name = name;

this.sex = sex;

//方法

this.intro = function(){

alert("姓名:" + this.name + "\n" + "性别:"+this.sex);

}

}

使用构造函数

//创建对象

var student = new Student("张三","男");

//调用方法

student.intro();

构造函数:用来构建对象的函数。

注意:1.为了区别普通函数,构造函数的函数名首字母规定应该为大写。2.构造函数必须使用new运算符来调用执行(实例化对象)。3.在构造函数里面写属性,在原型里面写方法


五、原型

1.通过new实例化出来的对象,其属性和行为来自于两个部分,一部分来自于构造函数,另一部分来自于原型.

2.当我们声明一个类时,其实同时生成了一个对应的原型.例如我们定义Person这个类时,会产生一个与Person类对应的原型prototype.

3.原型本身就是一个对象。

4.通过prototype可以指向这个原型,原型可以通过constructor指向Person类(构造函数).

function  Dog(){//构造函数

       this.name="大黄";

        this.sex="公";

}

Dog.prototype={//原型

      bark:function(){

      alert("汪汪~");

         }

}

//也可以这样写

//通过构造函数找到原型

Car.prototype={

action1:function() {

console.log("我是方法1")

},

action2:function() {

console.log("我是方法2")

},

}

//原型

//Car.prototype.action = function() {

//console.log("我是原型里的方法");

//}

function  Person() {

this.arr=[1,2,3];

}

//通过原型可以取到构造函数里面的东西

Person.prototype.hobby=function() {

console.log(this.arr);

}

var   newPerson= newPerson();

newPerson.hobby();


六、原型链

1.原型链:原型链是指对象在访问属性或方法时的查找方式。

2.当访问一个对象的属性或方法时,会先在对象自身上查找属性或方法是否存在,如果存在就使用对象自身的属性或方法。如果不存在就去创建对象的构造函数的原型对象中查找 ,依此类推,直到找到为止。如果到顶层对象中还找不到,则返回 undefined。

3.原型链最顶层为 Object 构造函数的 prototype 原型对象,给 Object.prototype 添加属性或方法可以被除 null 和undefined 之外的所有数据类型对象使用。


七、公有和私有

1.在传统的面向对象的语言中一般会提供public、protected、private等关键字来声明属性和方法的

公开性.

2.javascript中没有这些关键字,我们通过作用域来实现公有或者私有。

functionWomen(name,sex){

//公有属性

this.name=name;

this.sex=sex;

//私有属性

var_age="30";

//公有方法

this.eat=function(){

alert("");

}

//私有方法

var  fight=function(){

alert("!");

}

}

对于上述例子中,使用this.xxx定义的属性和方法是公有的,我们在外部使用对象很容进行访问.

使用 var xxx定义的属性和方法是私有的.只能在构造函数内部进行直接访问.

set方法:我们可以通过公有的方法去访问私有的属性.我们把给专门给私有属性赋值的方法称为set方法

get方法:我们把专门获取私有属性的方法称为get方法

function     Women(name){

      this.name=name;

      var     _age="30";

      //set方法

    this.setAge=function(age){

         _age=age;

     }

}

function    Women(name){

      this.name=name;

     var_age="30";

     //get方法

    this.getAge=function(){

        return     _age;

    }

}


八、继承

1.继承的目的是找到类之间的共性,精简代码。

2.原型不能直接被继承

//解决继承中原型的传址问题

function    Dad() {

this.name="杨幂";

this.age=18;

}

Dad.prototype.hobby=function() {

console.log("电视");

}

function    Son() {

this.name="小糯米";

Dad.call(this);

}

//创建一个新的对象就会新引用一个地址

Son.prototype= newDad();

Son.prototype.hobby=function() {

console.log("肉肉");

}

var      newDad= new   Dad();

newDad.hobby();


九、改变this指向

//下面三种方式可以改变this指向

var   o={

name:"张三",

age:"18"

}

function  test(name,age) {

 console.log(this);

}

//这时候this指向window

//test();

//通过call改变函数内部的this指向

//这时候this指向o

//test.call(o)

var    o={

name:"张三",

age:"18"

}

function   test(name,age) {

console.log("姓名"+name+"年龄"+age)

console.log(this);

}

//test.call(o,"张三",18)

//test.apply(o,["李四",36]);//第二个参数需要的是一个数组

//test.bind(o)("王五", 21);


十、传值和传址

传址:复杂的数据类型就会涉及到传址问题

传值:简单的数据类型,(一个简单的变量就是简单的数据)

//传值

var  a=10;

var   b=a;

var    b=5;

console.log(a)//10

//传址

var  arr1=[1,2,3,4];

var   arr2=arr1;

arr2[1]=5;

console.log(arr1);//[1,5,3,4]

//传址

var   obj1={

name:"coco",

age:18

};

var   obj2=obj1;

obj2.age=10;

console.log(obj1)//{name:"coco",age:10}

//传址造成的问题案例

function   Dad(height) {

this.name="王健林";

this.height=height;

this.money="$88888888888";

this.hobby=function() {

console.log("太极");

}

}

//js面向对象里面的继承,原型是不会被继承的

Dad.prototype.fun=function() {

console.log("高尔夫");

}

functionSon(height) {

this.name="王思聪";

//继承(就相当于把this指向的函数加到Dad里面)

//Dad.call(this, height);

//Dad.apply(this, [height]);

Dad.bind(this)(height);

}

//解决不能继承原型的问题

//这种方式,造成了两个fun的地址是在一起,改变一个,另一个也会被改变,传址

Son.prototype=Dad.prototype;

Son.prototype.fun=function() {

console.log("泡妞");

}

var   newDad= new    Dad();

newDad.fun();//泡妞


十一、深拷贝(克隆)

1.JSON.stringify()  将 [] 或 {} 的对象转换成字符串形式的值,就是编码

2.JSON.parse()  将字符串形式的 [] 或 {} 值转换成对象,就是解码

3.克隆实现原理:利用字符串赋值为传值的特点,先将对象转换成字符串形式,然后将字符串形式的值再转换成对象。

4.兼容问题:不支持低版本IE浏览器

//解决传址问题

//深拷贝,克隆

var   obj1={

name:"coco",

age:18

};

//编码json数据

//var _json = JSON.stringify(obj1);

//console.log(_json)

//console.log(typeof  _json) //string

//解码json串

//var obj2 = JSON.parse(_json);

//console.log(obj2);

//用深拷贝解决传址问题

var     obj2=JSON.parse(JSON.stringify(obj1));

obj2.age=13;

console.log(obj1);


十二、typeof的不足

typeof 可以准确地判断出简单数据类型,但对复杂数据类型的判断相对比较模糊。

比如: 数组对象 \ 时间对象 \ 正则对象 \ Math对象等都返回的是 ‘object’。

优化方案:封装函数
function type( obj ){

var o = {};

return o.toString.call(obj).slice(8,-1).toLowerCase();

}

实现原理:Object 对象的 prototype 的 toString() 方法会返回一个表示对象本身类型的字符串。

上一篇 下一篇

猜你喜欢

热点阅读