对象的遍历

对象可以当做数组处理,使用for in

var person={};
person.name="cyy";
person.age=25;
person.infos=function(){
alert(this.name+" "+this.age);
} for(var i in person){
console.log(i);//属性名或方法名
console.log(person[i]);//属性值或方法值
}

使用构造函数声明的对象,需要实例化之后再进行遍历

function Person(){
this.name="cyy";
this.age=25;
}
var p=new Person();
for(var i in p){
console.log(i+":"+p[i]);
}

对象在内存中的分布

参考以下神图

 封装:把对象的内部数据和操作细节进行隐藏

提供private关键词隐藏某些属性和方法,限制被封装的数据或者内容的访问,只对外提供一个对象的专门访问的接口

接口一般为调用方法

不过js没有提供这样的关键词,但可以通过闭包来实现

函数内部声明的变量,外部是访问不到的

function fn(){
var n=1;
function fn2(){//特权方法
alert(++n);
}
return fn2;
}
fn()();//
//封装
function Person(){
var name="cyy";
function _name(){
alert(name);
}
this.name=function(){//这是给外部的接口
return _name;
}
}
var p=new Person();
var fn=p.name();
fn();//cyy

封装的缺点:1、占用内存   2、不利于继承


利用闭包特性来封装一个对象student,运用对象student存储一个学生的信息,信息包括姓名,性别和年龄,这些信息不可被外部直接访问,只能通过对象的方法获取

student的数据结构如下:

//封装
function Student(){
var obj={};
function _set(name,sex,age){
obj.name=name;
obj.sex=sex;
obj.age=age;
}
function _get(){
return obj.name+" "+obj.sex+" "+obj.age;
}
obj.get=function(){//对外接口
return _get;
}
obj.set=function(){//对外接口
return _set;
}
return obj;
}
var stu=new Student;
stu.set()("小明", "男", 23);
console.log(stu.get()());//小明 男 23

原型和原型链

原型:利用 prototype 添加属性和方法,prototype对象

原型链:JS在创建对象时,有一个 __proto__ 的内置属性,指向它的原型对象 prototype

var Person=function(){}
var p=new Person();
Person.prototype.say=function(){
alert("老娘超美");
}
p.say();
/*
p没有say方法,所以会去p.__proto__里找
p.__proto__是一个对象,指向Person.prototype
Person.prototype中有say方法
*/ /*
创建对象的过程
1、创建对象 var p={}
2、将Person的原型对象赋值给p p.__proto__=Person.prototype
3、初始化对象p Person.call(p)
*/
alert(p.__proto__==Person.prototype);//true

原型和原型链,实现原型继承

var Person=function(){}//Person是一个对象
Person.prototype.say=function(){
alert("陈莺莺超美");
}
var Cyy=function(){};//Cyy也是一个对象
Cyy.prototype=new Person();//将Cyy的原型指向Person,实现Cyy继承自Person
Cyy.prototype.sing=function(){
alert("陈莺莺会唱歌");
} var me=new Cyy();
me.say();//陈莺莺超美
me.sing();// 陈莺莺会唱歌 /*
分析:me.__proto__ -> Cyy.ptototype -> Person.prototype
Person是父 Cyy是子
继承:如果子类中没有的,会继承自父类;如果子类和父类中都有,那么子类的会覆盖掉父类的
*/

__proto__ 实现原型继承

function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.say=function(){
alert(this.name+" "+this.age);
} function Student(){};
Student.prototype=new Person("cyy",25);
//Person是Student的父类
//子类必须继承自父类的实例
Student.prototype.grade=3;
Student.prototype.test=function(){
alert(this.grade);
} var s=new Student();
s.say();//cyy 25
s.test();//
//s.__proto__ -> Student.prototype -> Person.prototype

原型的值可以是一个对象,也可以是null

原型链的最终指向null

alert(Object.prototype.__proto__);//null
// 情况一
function Parent(){
this.name="parent";
this.age=45;
}
function Child(){
this.age=25;
}
Child.prototype.name="child";
Child.prototype=new Parent();
var c=new Child();
console.log(c.name);//parent // 情况二
function Parent(){
this.name="parent";
this.age=45;
}
function Child(){
this.age=25;
}
Child.prototype=new Parent();
Child.prototype.name="child";
var c=new Child();
console.log(c.name);//child

情况一中,Child.prototype=new Parent(); 这一句覆盖掉了前面的 Child.prototype.name="child";

属性的值与代码执行顺序有关,后继承的父级的,会覆盖住先定义的自己的


创建一个动物类的对象 ,对象中有动物名称和数量的属性 。创建一个猫的对象并继承动物类对象 ,并为猫对象定义一个方法 。实例化一个猫对象 ,调用其方法 ,弹出动物名称和数量

function Animal(name,number){
this.name=name;
this.number=number;
}
function Cat(){};
Cat.prototype=new Animal("cat",30);
Cat.prototype.info=function(){
alert(this.name+" "+this.number);
}
var c=new Cat();
c.info();//cat 30

构造函数的继承

在子类内部构造父类的对象来实现继承

父对象被子对象继承后,所有的属性和方法,都会传递到子对象中

function Parent(name){
this.name=name;
this.pSay=function(){
alert(this.name);
}
}
function Child(name,age){
this.obj=Parent;
this.obj(name);//继承了父元素中的两句代码
this.age=age;
this.cSay=function(){
alert(this.name+" "+this.age);
}
}
var p=new Parent("爸爸");
p.pSay();//爸爸
var c=new Child("女儿",25);
c.cSay();//女儿 25
c.pSay();//女儿

对象内置方法中的apply和call都可用于继承,两者的区别在于传参方式不同

obj.call( 方法, var1, var2...)

obj.apply( 方法, [var1, var2...])

function Parent(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
this.say=function(){
alert(this.name+" "+this.age+" "+this.sex);
}
}
function Child(name,age){
//实现继承
Parent.call(this,name,age);//this是指Child
}
function Child2(name,age){
//实现继承
Parent.apply(this,[name,age]);//this是指Child
} var c=new Child("cyy",25);
c.say();
//cyy 25 undefined
//Child也拥有了Parent的属性和方法
var c2=new Child2("cyy2",25);
c2.say();//cyy2 25 undefined

使用构造方法创建一个动物类对象Animal, 对象中定义属性有动物名称和数量 ,并且定义一个方法。再创建两个动物的对象(如猫和狗),一个动物使用call方法实现继承Animal, 一个动物使用apply方法实现继承Animal。分别实例化两个动物并弹出动物的名称和数量

function Animal(name,num){
this.name=name;
this.num=num;
this.getInfo=function(){
alert(this.name+" "+this.num);
}
}
function Cat(name,num){
Animal.call(this,name,num);
}
function Dog(name,num){
Animal.apply(this,[name,num]);
}
var c=new Cat("cat",20);
c.getInfo();//cat 20
var d=new Dog("dog",30);
d.getInfo();//dog 30

JS面向对象的关键词

instanceof  变量是否是对象的实例

var arr=new Array();
console.log(arr instanceof Array);//true
console.log(arr instanceof Object);//true function Person(){};
var p=new Person();
console.log(p instanceof Person);//true
console.log(p instanceof Object);//true

delete 删除对象属性(不能删除原型链中的属性和方法

function Person(){
this.name="cyy";
this.eat=function(){
alert("吃饭");
}
}
var p=new Person();
console.log(p.name);//cyy
delete p.name;//删除对象的属性
console.log(p.name);//undefined p.eat();//吃饭
delete p.eat();//吃饭 删除对象的方法,失败
p.eat();//吃饭 var name="cyy";
console.log(name);//cyy
delete name;
console.log(name);//name is not defined

call 参数逐个实现继承

apply 参数以数组方式实现继承

function add(a,b){
alert(a+b);
}
function sub(a,b){
alert(a-b);
}
add.call(sub,4,8);
//12 调用的是add这个方法
add.call(sub2,4,8);
//sub2 is not defined 只能引用一个已经存在的对象 add.apply(sub,[3,2]);
function Animal(){
this.name="animal";
this.show=function(){
alert(this.name);
}
}
function Cat(){
this.name="cat";
}
var a=new Animal();
var c=new Cat();
a.show.call(c);//cat c拥有了a所拥有的show方法
a.show.apply(c,[]);//cat c拥有了a所拥有的show方法

创建两个数组 ,并运用apply实现两个数组的拼接

var arr1=[2,3];
var arr2=[4,5];
arr1.push.apply(arr1,arr2);
//调用的是apply前面的方法:arr1.push
console.log(arr1);

arguments 实参的类数组对象

callee  返回正在执行的function对象,返回的是function的内容

arguments.callee

function fn(){
console.log(arguments.callee);
/*ƒ fn(){
console.log(arguments.callee);
}
*/
//console.log(arguments.callee());不停调用自身,陷入死循环
}
fn();

常用于递归函数调用函数自身

var sum=function(n){
if(n<=1) return 1;
return n+sum(n-1);
}
console.log(sum(4));//
var sum=function(n){
if(n<=1) return 1;
return n+arguments.callee(n-1);
}
console.log(sum(4));//

this 指向当前对象

1、this函数调用

var x=1;
function fn(){
this.x=2;//this改变的是全局变量的x的值
}
fn();
console.log(x);//

2、this作为方法调用

构造函数内指代当前对象

function Person(){
this.name="cyy";
this.show=function(){
alert(this.name);
}
}
var p=new Person();
p.show();//cyy

3、在call和apply中,this作为第一个参数

var name="cyy";
function show(){
alert(this.name);
}
var obj={};
obj.name="cyy2";
obj.showName=show;
obj.showName.apply();//调用show(),this指向全局
obj.showName.apply(window);//同上
obj.showName.apply(obj);//调用show(),this指向obj

用arguments计算参数总和

function sum(){
var sum=0;
for(var i=0;i<arguments.length;i++){
sum+=arguments[i];
}
return sum;
}
console.log(sum(2,5,7));//

对象冒充:将父类的属性和方法传给子类,作为特权属性和特权方法

function Parent(name,age){
this.name=name;//特权属性
this.age=age;
this.show=function(){//特权方法
alert(this.name+" "+this.age);
}
}
Parent.prototype.walk=function(){//非特权方法
alert("walking...");
} function Child(name,age,sex){
this.obj=Parent;//对象冒充,可以使用父类的特权属性和特权方法
this.obj(name,age);
this.sex=sex;
}
var c=new Child("cyy",25,"女");
c.show();//cyy 25
c.walk();// c.walk is not a function

JS对象的概念、声明方式等及js中的继承与封装的更多相关文章

  1. Xamarin XAML语言教程对象元素的声明方式

    Xamarin XAML语言教程对象元素的声明方式 XAML的对象元素的声明有两种形式,分别为包含属性的特性语法形式以及对象元素语法形式.在1.4小节中,我们看到了其中一种对XAML对象元素的声明方式 ...

  2. 创建Vue.js对象:我的第一个Vue.js输出信息

    <!DOCTYPE html><html><head><meta charset=”utf-8″><title>Vue第一条信息</t ...

  3. 判断js对象是否拥有某一个属性的js代码

    js对象是否拥有某一个属性的判断方法有很多. 本文分享一个简单的方法,如下: <script> /** * 判断js对象是否具有某属性 * by www.jbxue.com */ var ...

  4. 浅谈Js对象的概念、创建、调用、删除、修改!

    一.我们经常困惑,对象究竟是什么,其实这是一种思维,一种意识上的东西,就像我们都说    世界是有物质组成的道理一样,理解了下面的几句话!对象也不是那么抽象!    1.javascript中的所有事 ...

  5. 取出js对象的所有属性的方式

    例子: //取出事件的所有属性 $('#id_btn').bind("click dbclick mouseout",{crdx:'我是传的值'},function(e){ var ...

  6. js对象系列【二】深入理解js函数,详解作用域与作用域链。

    这次说一下对象具体的一个实例:函数,以及其对应的作用域与作用域链.简单的东西大家查下API就行了,这里我更多的是分享自己的理解与技巧.对于作用域和作用域链,相信绝大多数朋友看了我的分享都能基本理解,少 ...

  7. JavaScript学习12 JS中定义对象的几种方式

    JavaScript学习12 JS中定义对象的几种方式 JavaScript中没有类的概念,只有对象. 在JavaScript中定义对象可以采用以下几种方式: 1.基于已有对象扩充其属性和方法 2.工 ...

  8. js对象小结

    前奏 对象是js的基本数据类型,准确来说除了字符串,数字,boolean值,null与undifine之外,js中的值都是对象.js中的对象是一种复合值,他将很多值(原始值或其他对象)聚合在一起,可以 ...

  9. 3、获取Class对象的三种方式

    3.获取Class对象的三种方式 要想对字节码文件进行解刨,必须要有字节码文件对象 Object类中的getClass方法 通过对象静态属性 .class来获取对应的Class对象 只要通过给定类的字 ...

随机推荐

  1. MySQL数据库之xtrabackup物理备份(一)

    前言:说到数据库备份,我们知道可以用来对数据库进行备份的工具有mysqldump.mydumer.mysqlpump等等,实际工作中,机器上的数据库不大的话,都是用mysqldump工具来备份,这些备 ...

  2. 个人第4次作业—Alpha项目测试

    这个作业属于哪个课程 课程链接 这个作业要求在哪里 作业要求 团队名称 CTRL_IKUN(团队博客) 这个作业的目标 对非本小组的三个项目进行软件测试 一.测试人员个人信息 学号 201731032 ...

  3. 龙芯 fedora28 安装指南

    版权声明:原创文章,未经博主允许不得转载 关于硬件 龙芯3号的板子安装系统都差不多,我分别在 Lemote A1310 和 Lemote A1901 上都尝试过. 本文主要依据 Lemote A190 ...

  4. UML--->用例图梳理

    用例图梳理 概述 用例图主要用来描述"用户.需求.系统功能单元"之间的关系.它展示了一个外部用户能够观察到的系统功能模型图. 用例图的主要目的是帮助开发团队以一种可视化的方式理解系 ...

  5. Shell之哈希表

    前言 linux系统下会有一个hash表,当你刚开机时这个hash表为空,每当你执行过一条命令时,hash表会记录下这条命令的路径,就相当于缓存一样.第一次执行命令shell解释器默认的会从PATH路 ...

  6. Spring博客专栏

    1. IOC和DI的理解 2. IOC的实现原理-反射与工厂模式 3. Spring进阶之路 4. SpringBoot配置类的使用 5. @ModelAttribute详解 6. @RequestP ...

  7. Iptables和Firewall-selinux

    一.Iptables防火墙 ---------- **三表五链:**三表: filter过滤表 nat转换表 mangle表五链: PREROUTING--->在进行路由选择前处理数据包 INP ...

  8. 项目SpringMVC+Spring+Mybatis 整合环境搭建(2)-> 测试Spring+Mybatis 环境

    测试前期准备 第一步:创建easybuy数据库,设置utf-8格式 第二步:创建表test_tb CREATE TABLE `test_tb` ( `id` int(11) NOT NULL AUTO ...

  9. #使用abp框架与vue一步一步写我是月老的小工具(2) 后台搭建初体验

    #使用abp框架与vue一步一步写我是月老的小工具(2) 后台搭建初体验 一.续上前言 关于这个小玩意的产品思考,假设我暂时把他叫我是月老热心人 这是一个没有中心的关系链,每个人进入以后都是以自己为中 ...

  10. 实验13:VLAN/TRUNK/VTP/

    实验10-1: 划分VLAN Ø    实验目的通过本实验,读者可以掌握如下技能:(1) 熟悉VLAN 的创建(2) 把交换机接口划分到特定VLAN Ø    实验拓扑 实验步骤要配置VLAN,首先要 ...