JavaScript之面向对象


一、面向对象

1、对象创建方式

1.1、调用系统函数创建对象

(创建对象的最简单方式就是创建一个Object的实例,然后再为它添加属性和方法。)

var obj = new Object();
undefined
obj.name = "chris";
"chris"
obj.age = 88;
88
obj.eat = function () {
    console.log("我能玩");
};
ƒ () {
    console.log("我能玩");
}

缺点:使用同一个接口创建很多对象,会产生大量的重复代码。

1.2 自定义构造函数创建对象

工厂模式创建对象: 考虑到 ECMAScript 中无法创建类, 开发人员就发明了一种函数,用函数来封装以特定接口创建对象的细节(把创建一个对象的过程封装在一个函数里),缺点:创建的对象属性都是一样的。

function creatObject() {
    var obj = new Object();
    obj.name = "chris";
    obj.age = 22;
    obj.eat = function () {
        console.log("我很能吃");
    };
    return obj;
}
undefined
var person = creatObject();
undefined
person.age
22
person.eat();
VM450:6 我很能吃
undefined

工厂模式创建对象进阶版:可以修改属性

function createObject (name,age) {
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.eat = function () {
        console.log("我很能吃");
    }
    return obj;
};

var person = createObject("chris",33);
undefined
person.age
33
person.eat();
VM766:6 我很能吃

自定义构造函数: (函数和构造函数没有区别: 没有区别,但是通常构造函数首字母大写)

特点:

  • 没有显示式地创建对象;
  • 直接将属性和方法赋值给了 this 对象;
  • 没有 return 语句。
function CreateObject() {
    this.name = "chris";
    this.age =23;
    this.play = function () {
        console.log("paly football");
    }
};
undefined
var person1 = new CreateObject();     // 一定要和 new 一起使用,否则不行
undefined
person1.play();
VM1086:5 paly football

进阶 (传参数):

function CreateObject(name,age) {
    this.name = name;
    this.age = age;
    this.sing = function () {
        console.log("正在唱歌");
    }
};
var girl = new CreateObject("lily",23);
undefined
girl.name
"lily"

构造函数的问题:

构造函数模式虽然好用,但也并非没有缺点。使用构造函数的主要问题,就是每个方法都要在每个实例上重新创建一遍。---ECMAScript 中的函数是对象,因此每定义一个函数,也就是实例化了一个对象。从逻辑上来讲,此时构造函数也可以这样定义。

function Person(name,age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = new Function("alert(this.name)");  // 与声明函数在逻辑上等价的
};
undefined
var p1 = new Person('lily',23,'promotion');
undefined
p1
Person{name: "lily", age: 23, job: "promotion", sayName: ƒ}
p1.sayName();
undefined


var function_name = new Function(arg1, arg2, ..., argN, function_body)

从这个角度来看构造函数,更容易明白每个 person 实例都包含一个不同的 Function 实例(以显示name属性)的本质 。说明白些,以这种方式创建函数,会导致不同的 作用域链 和 标识符 解析,但创建Function 新实例的机制仍然是相同的。因此,不同实例上的同名函数是不相等的,以下代码可以证明这一点:

alert(person1.sayName == person2.sayName);   // false

然而,创建两个完成同样任务的Function实例的确没有必要;况且有 this 对象在,根本不用在执行代码前就把函数绑定到特定对象上面。因此,大可像下面这样,通过把函数定义转移到构造函数外部来解决这个问题。

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = sayName;
}

function sayName(){
    alert(this.name);
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");

在这个例子吕,我们把sayName() 函数的定义转移到了构造函数外部。而在构造函数内部,我们将 sayName 属性设置成等于全局的 sayName 函数。这样一来, 由于sayName 包含的是一个指向函数的指针,因此 person1 和 person2 对象就共享了在全局作用域中定义的一个 sayName() 函数。

1.3、使用对象字面量表示法(有的又叫直接量表示法)

对象字面量是对象定义的一种简写形式,目的在于简化创建包含大量属性的对象的过程。

如果留空其花括号,则可以定义只包含默认属性和方法的对象。

var person = {};   // new Object()相同

缺点:一次性对象,无法修改属性的值。

var obj = {
    name: "Chris",   // 注意是属性赋值是冒号
    age: 18;
    eat: function() {
    console.log("我爱吃鱼");
   }   // 最后一个后面没有逗号
};
obj.eat()

访问对象属性

点表示 法 和 方括号表示方法

alert(obj.name);
alert(obj["name"]);

从功能上看,这两种访问对象属性的方法没有任何区别。但方括号语法的主要优点是可以通过变量来访问属性(属性绑定),例如:

var propertName = "name";
alert(obj[properName]);

如果属性中包含会导致语法错误的字符,或者属性名使用的使关键字或保留字,也可以使用方括号表示法。

例如:

obj["first name"] = "Nicholas"

由于"first name" 中包含一个空格,所以不能使用 点表示法 来访问它。然而,属性名中是可以包含非字母和非数字的,这时候就可以使用方括号表示 法来访问它们。通常,除非必须使用变量来访问属性,否则我们建议使用点表示法。

PS: 如果 访问一个没有属性的值,那么这个值 为 undefined ,而不是报错。

因为 js 是一门动态类型的语言,不管使用点表示法还是方括号表示法,如果没有这个属性,就相当于在创建这个属性,然而这个时候没有赋值 ,所以就是 undefined 。

3、访问对象的方法

对象名.函数名();

4. JSON

什么是JSON

JSON 的全称为:JavaScript Object Notation (JavaScript 对象表示 形式:就是对象字面量)

JSON格式的数据: 一般都是成对的,键值对。

JSON 和 对象字面量的区别?

json 和 对象 (对象字面量) 的区别仅仅在于,json 格式的数据中的键必须 用双引号起来。

var json = '{names: ["www","bb"]}';  // 这是json 字符串
undefined
var obj = JSON.parse(json);
VM2207:1 Uncaught SyntaxError: Unexpected token n in JSON at position 1
    at JSON.parse (<anonymous>)
    at <anonymous>:1:16
(anonymous) @ VM2206:1
var json = '{"names": ["www","bb"]}';
undefined
var obj = JSON.parse(json);   // 将 json字符串 转换为 json对象
undefined
obj
{names: Array(2)}
obj.names
(2)["www", "bb"]

//  这里证明了json的格式字符串中的字符串必须用双引号
var json = "[1,3,'name']";     // 数据单引号报错  
undefined
var obj = JSON.parse(json);
VM2318:1 Uncaught SyntaxError: Unexpected token ' in JSON at position 5
    at JSON.parse (<anonymous>)
    at <anonymous>:1:16
(anonymous) @ VM2317:1
var json = '[1,3,"name"]';   // 这是json格式数组字符串
undefined
var obj = JSON.parse(json);
undefined

// 以下演示证明了json字符串的键必须用 比双引号 引起来
var json ="{names: [1,3,5]}";
undefined
var obj = JSON.parse(json);
VM2484:1 Uncaught SyntaxError: Unexpected token n in JSON at position 1
    at JSON.parse (<anonymous>)
    at <anonymous>:1:16
(anonymous) @ VM2483:1
var json ="{'names': [1,3,5]}";
undefined
var obj = JSON.parse(json);
VM2494:1 Uncaught SyntaxError: Unexpected token ' in JSON at position 1
    at JSON.parse (<anonymous>)
    at <anonymous>:1:16
(anonymous) @ VM2493:1
var json ='{"names": [1,3,5]}';
undefined
var obj = JSON.parse(json);
undefined
obj.names
(3)[1, 3, 5]

// 这是 创建了一个json对象
var json = {
    "name" : "zs",
    "age" : 18,
    "sex" : true,
    "sayHi" : function() {
        console.log(this.name);
    }
};   
undefined
json.sayHi();
VM2524:6 zs

// json 数组对象
var json = [
    {"name":"Runoob", "url":"www.runoob.com"}, 
    {"name":"Google", "url":"www.google.com"},
    {"name":"Taobao", "url":"www.taobao.com"}
]
undefined
json
(3)[{…}, {…}, {…}]
json[0].name
"Runoob"

// json对象本身没有 length ,所以不能用for 循环遍历。要使用for ... in ...
var json = {
    "name" : "zs",
    "age" : 18,
    "sex" : true,
    "sayHi" : function() {
        console.log(this.name);
    }
};   
undefined
json.length
undefined
for (var key in json) {
    // key 代表 name, age,sex, sayHi 。。。
    console.log(json[key]);
}
VM2792:3 zs
VM2792:3 18
VM2792:3 true
VM2792:3 ƒ () {
        console.log(this.name);
    }

5、字面量的遍历

对象本身没有length, 所以不能用for 循环遍历。要使用 for ... in ...

var json = {“aaa”: 1, “bbb”: 2, “ccc”: 3, “ddd”: 4}

for(var key in json){
    //key代表aaa,bbb.....等
    //json[key]代表1,2,3....等(k 不要加引号)
}

6、 值传递 和引用类型传递

分析值传递和地址传递最好的方法就是画图分析法,最简单。

7、内置对象

Math, Date, String, Array

学习的时候可以查阅在线文档

MDN在线文档:https://developer.mozilla.org/zh-CN/

菜鸟教程:

8、基本包装类型

本身是基本类型,但是在执行的过程中,如果 这种类型的变量调用了属性 或者 方法,那么这种类型就不是基本类型了,而是基本包装类型。这个变量也不是普通变量了,而是基本包装类型的变量。

var str = "hello";
undefined
typeof str;
"string"
str = str.replace("hel","woo");
"woolo"
console.log(str);
VM2924:1 woolo

需要注意的地方:

如果一个对象 对象 && true , 那么结果是true

如果 一个对象 true && 对象 ,那么结果 是对象

var obj = new Object();
undefined
obj && true;
true
true && obj;
{}

不用搞得这么复杂 推荐大家看这部分的说明
a && b : 将a, b转换为Boolean类型, 再执行逻辑与, true返回b, false返回a
a || b : 将a, b转换为Boolean类型, 再执行逻辑或, true返回a, false返回b
转换规则:
对象为true
非零数字为true
非空字符串为true
其他为false

var num = 10; // 基本类型
var num2 = Number("10"); // 不是基本包装类型,而是转换
var num3 = new Number("10"); // 这才是基本包半类型 
优质内容筛选与推荐>>
1、选择器
2、一些特效,不断更新
3、要想着以后总有人来维护你的代码
4、Zookeeper工作原理二
5、div_固定table表头


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号