2018-11-22 面向对象3

JavaScript的面向对象是基于constructor(构造函数)与prototype(原型链)的。

1.构造函数:constructor

构造函数就是一个函数。和普通函数有一些区别:

  • 函数的内部使用this的关键字。
  • 首字母是大写的。
  • 使用的时候要用new操作符创建实例对象。
2.原型:prototype

原型是一个对象,称为原型对象。
构造函数创建实例对象,构造函数具有原型,实例对象也具有原型。实例对象的原型指向构造函数的原型。这就是原型链。

3.原型链:
4.proto:每一个实例对象都具有的私有属性。指向自己的原型。

proto属性(前后各两个下划线),用来读取或设置当前对象的prototype对象。目前,所有浏览器(包括 IE11)都部署了这个属性。
eg:1__protp___
效果如下:

22.proto.jpg

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script>
let a = new Array();
console.log(a);

function A(){
    this.a = '1';
}
let b = new A();
console.log(b.__proto__)
console.log(A)
</script>
</html>

constructor: 构造器。指向自己的构造函数。

5.new :

创建对象实例。
防止漏掉new造成错误:
在构造函数内部使用严格模式。
使用instanceof在内部判断。判断是否为当前对象的实例。
使用new.target 在内部判断,new.target指向自己的构造函数。
eg:2new
效果如下:


22.new1.jpg
22.new1.1.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script>
ll = 'lala';
function A(name){
    console.log(this);      //此处的this指代的是全局作用域window
    this.ll = name;
    function ss(){
        alert(this.ll);
    }
}
A.prototype.say  = function(){
    alert(this.ll);
}
/*
let a = new A ('zhangsan');
a.say();    //页面弹出“zhangsan”的字样打印A{}的数组
*/
let a = A('lili');
console.log(ll)     //页面打印window的全局作用域 、 lili
</script>
</html>

eg:3new
效果如下:


22.new2.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script>
function A (name){
    'use strict';  //严格模式
    this.name = name;
}

let a = new A('lisi');

//递归
function  B(name){
    // this指向新创建的实例
    if(!(this instanceof B)){
        return new B(name);
    }
    this.name = name;
}
let b = new B('lili');
console.log(b.name);
let bb = B ('sisi');
console.log(bb.name);

//new.target指向自己的构造函数
function V (name){
    if(!(new.target == V)){
        throw new Error('这个对象必须使用new来创建对象');
    }
    this.name = name;
}
let v  = new V('kk');
let vv = V('kk');
</script>
</html>
6.new的深入操作:

1.创建一个空对象,作为将要返回的对象实例。
2.将这个空对象的原型,指向构造函数的prototype属性。
3.将这个空对象赋值给函数内部的this关键字。
4.开始执行构造函数内部的代码。
5.将对象实例返回
eg:4new
效果如下:


22.new3.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script>
function A(name){
    this.name = name;
    return  123;    //简单数据类型
}
let a = new A('123');
console.log(a);     //打印出的是A数组里面的内容

function B(name){
    this.name = name;
    return this;
}
let b = new B('123645');
console.log(b);     //打印出的是B数组里面的内容


function C(name){
        this.name = name;
        return {
            name:'zhangsan'
        };
}
let c = new C('1689156');
console.log(c);    //打印出的是C数组里面的内容
</script>
</html>
7.构造函数里面的return语句:

如果return的是普通数据类型。那么相当于没写。
如果返回的是this,那么返回的与本身返回的是一样的。
如果返回的是一个其他对象。那么结果返回的就是这个对象。所以在构造函数内部返回对象要小心。

8.任何一个函数都可以使用new。返回值都是一个对象。

如果这个函数是一个构造函数的话,返回的是这个函数的实例。
如果函数是一个普通函数,那么返回的是一个空的对象。

9.Object对象,是所有JS对象的基础。

Object 的原型指向null。一切对象的基础是null,null也叫空。
eg: 5 Object
效果如下:


22.5Object.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script>
console.log(Object.prototype.__proto__);    //打印得null说明打印出的是对象原型是空
</script>
</html>
9.(1)Object.create();

有的时候我们拿不到对象的构造函数。可以根据这个对象的某一个实例去创建一个对象。
eg:6create
效果如下:


22.6create.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script>
function A(name){
    this.name = name;
}
let a = new A('LILI');

let b = Object.create(a);       //有的时候我们拿不到对象的构造函数。可以根据这个对象的某一个实例去创建一个对象。

console.log(b);     //A name: "zhangsan"__proto__: A  此处获取的是b.name的命名'zhangsan'

b.name = 'zhangsan';
console.log(a.name);    //LILI 此处获取的是a中为A创建的一个实例'LILI'
</script>
</html>

对于对象来说,每一个属性 其实都有四个描述。
value 值
enumerable 枚举 遍历 for in
configurable 修改
writable 删除
后面三个默认值都是true。
eg:7create
效果如下:


22.7create.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script>
let obj = new Object();
//添加属性
obj.p1 = 'lili';
obj.p2 = 16;

let obj2 = Object.create(obj,{  //有的时候我们拿不到对象的构造函数。可以根据这个对象的某一个实例去创建一个对象。(后面三个默认值都是true。)
    /*value:值
    enumerable:true,
    configurable:true,
    writable:true
    */

    p1:{
        value:'llaaa',
        enumerable:false,       //*
    },
    p2:{
        value:56,
        enumerable:true,
        configurable:true,
        writable:true,
    }
});
for(let i in obj){  //让i拥有obj的值
    console.log(i,obj2[i]);     //打印出p1 llaaa, p2 56
}
</script>
</html>

eg:8.enumerable
效果如下:


22.8enumerable.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script>
var obj = {
    a:'a',
    b:'b',
    c:'c',
};
for(let i in obj){  //让i拥有obj的值
    console.log(i,obj[i]);
}
console.log('___________________________')
Object.defineProperty(obj,'c',{
    value:13,
    //可枚举性(enumerable)用来控制所描述的属性,是否将被包括在for...in循环之中。一般enumerable后面跟的值true
    enumerable:false,
});
for(let i in obj){
    console.log(i,obj[i]);
}
</script>
</html>
9.(2)Object.getPrototypeOf(obj)

获取obj对象实例的原型
eg:9Object.getPrototypeOf
效果如下:


22.9getprototypeof.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script>
function A(name){
    this.name = name;
}
let a = new A('lili');
console.log(Object.getPrototypeOf(a));  //获取对象原型
console.log(a.__proto__)
Object.getPrototypeOf({}) === Object.prototype  //true
//new Object 与Object的原型是一致的。对象的原型与构造函数的原型是一致的。

Object.getPrototypeOf({})===null

//Object对象的原型的原型指向null。null也是原型链的顶点。

function f(){}
    Object.getPrototypeOf(f)===Function.prototype  //true
//构造函数的原型与内置对象function的原型相同。f=== new Function();

</script>
</html>
9.(3)Object.prototype.isPrototypeOf() 判断该对象是否为参数对象的原型

eg:console.log(Array.prototype.isPrototypeOf(b));

obj1.isPrototypeOf(obj2)
判断obj2的原型是否是obj1。

9.(4)Object.setPrototypeOf(obj)设置obj对象实例的原型

eg:10setPrototypeOf
效果如下:


22.10Object.setPrototypeOf.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script>
let a = new Array();
//Object.getPrototypeOf(obj)获取obj对象实例的原型
console.log(Object.getPrototypeOf(a));
//Object.setPrototypeOf(obj)设置obj对象实例的原型
Object.setPrototypeOf(a,Number.prototype);

console.log(Object.getPrototypeOf(a));
</script>
</html>
9.(5)Object.getOwnPropertyNames() 成员是参数对象本身的所有属性的键名,不包含继承的属性键名。

eg:12Object.getOwnPropertyNames()
效果如下:


22.12Object.getOwnPropertyNames().jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script>
function A(name){
    this.name=name;
    this.say = function(){
        console.log(a);
    }
}
A.prototype.ss = function(){
    console.log('ss');
}

function B(name){
    A.call(this);
        this.age = 16,
        this.sex = 'man'

};
for(let i in A.prototype){
    B.prototype[i] = A.prototype[i];
}
let b = new B ('lala');
b.ss();
//Object.getOwnPropertyNames()    成员是参数对象本身的所有属性的键名,不包含继承的属性键名。
console.log(B.prototype.hasOwnProperty('say'));     //ss  false
</script>
</html>
9.(6)Object.prototype.hasOwnProperty() 用于判断某个属性定义在对象自身,还是定义在原型链上。
10.函数属性的区别:
  • 私有属性 : 在对象的定义中定义的非全局变量(在对象的定义中定义的非全局变量这种方式定义的属性,类的实例不能访问;只能通过 类名.属性名访问)
  • 实例属性 : 使用this为对象附加实例属性/对象名称.属性名(这种方式定义的属性,只能通过类的实例访问.不同实例之间共享该属性;不能通过 类名.属性名的方式访问)
  • 类属性 : "类"名.属性名/类名.prototype.属性名
    eg:13私有属性与实例属性
    效果如下:
    22.13私有属性.jpg
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script>
function F(name){
    A.call(this);   
    B.call(this);      //此处的A.call 与B.call是属于实例函数   这种方式定义的属性,只能通过类的实例访问.不同实例之间共享该属性;不能通过 类名.属性名的方式访问
    let ll = name ;   //私有成员  此处的‘ll’是私有属性私有属性  在对象的定义中定义的非全局变量这种方式定义的属性,类的实例不能访问;只能通过 类名.属性名访问
    this.getName = function(){
        console.log(ll);
    }
}

let f = new F('lili');

f.getName();
</script>
</html>
11.命名空间

eg:14命名空间

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script>
//适用于大型项目组


//在所有的调用函数前设置一个qq的命名,让所有的要调用的函数都包含在qq中以避免与项目组的成员之间的项目函数调用重名
var qq= {
    this.F = function(){

    }
    this.S = function(){

    }
};

li.F()
</script>
</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容

  •   面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意...
    霜天晓阅读 2,107评论 0 6
  • 面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的慨念,而通过类可以创建任意多个...
    threetowns阅读 876评论 0 4
  • 事情要从朋友带孩子参加一个暑期国学孝道夏令营开始说起。朋友是一个体制内工作者,有个8岁上小学二年级的儿子,平时非常...
    千光一阅读 4,847评论 20 23
  • 第四天 心灵的探索,佛家时间观,改变未来,重设生命程式 1、每天都要快乐的生活么? 心:对,只有当你快乐了,你所散...
    喜云阅读 165评论 0 0
  • 路漫漫其修远兮,吾将上下而求索。人生这条路平凡而又坎坷,每走一段路都要歇歇脚总结一下这一路的艰辛,整理一下自己的状...
    耕耘生活阅读 1,034评论 4 13