您的位置:首页 > Web前端 > JavaScript

JavaScript面向对象之----各种方法的创建以及使用以及介绍

2016-11-22 16:29 507 查看
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>

</body>
</html>
<script type="text/javascript" charset="utf-8" async defer>
/**
* 对象是神马?
*/

/*
对象是JavaScript的基础,在JavaScript中一切都是对象,JavaScript的多数能力也正起源于此,在其最根本的层面上,对象对象作为属性的集合存在,差不多类似于你在其他语言中看到的哈希概念
*/

// 创建一个新对象并将它存放在obj里面
var obj = new Object();
// 为该对象设置一些属性和方法
obj.val = 5;
obj.click=function(){
alert('hello')
};

// 下面这个是等效代码,只不过使用了{}的编写方式
var obj = {
// 在对象里面采用 key:val
vak:5,
click:function(){
alert('hello')
}
}
// 实际上对象就这么回事了。然而,事情变得麻烦的地方,在于新对象(尤其是那些继承其它对象属性的对象)的创建

/**
* 如何创建一个对象
*/

/*
不像大多数其它面向对象的语言,JavaScript 实际上并没有类的概念。在大多数其它的面向对象语言中,你可以初始化一个特定的类的实例,但是在 JavaScript 中的情况这是这样。在 JavaScript 中,对象能够创建新的对象,对象可以从继承自其它对象。整个概念被称为"prototypal inheritance"(原型标本继承),将在"公有方法"一节中有更多论述。然而,重要的是,不论 JavaScript采用哪种对象方案,总归要有一个方式来创建新的对象。JavaScript的做法是,任何一个函数也都能作为一个对象被实例化。实际上,事情听起来远比它本身更令人困惑。好比有一块生面团(相当于原始的对象),用小甜饼切割器(相当于对象构造器,使用对象的原型 prototype)为其成形。
*/

//一个简单的函数,接受一个参数 name,并将其保存于当前上下文中
function User( name ) {
this.name = name;
console.info(this.name)
console.warn(window.name)
}
// 创建上面函数的一个实例 [每次我们创建一个新对象的时候,this指向的属性和方法都会得到相应的创建]
var me = new User('pangchengyong');
// name已经成为me对象的一个属性了
// alert(me.name)

// me它的确是User对象的一个实例 【检测某个实例是不是由一个对象得来的使用constructor】
// alert(me.constructor == User)

//当我们这么处理它的时候,发生了什么?
// User( "Test" );
//因为 this 上下文没有被设置,它缺省地指向全局的 window 对象
// 这意味着 window.name 将等于我们提供给它的那个name
// console.info( window.name == "Test" );

/*
上面介绍了 constructor 属性的使用。
这个存在于每一个对象中的属性将总是指向创建该对象的那个函数。于是,你可以方便的复制该对象,创建一个新的有共同基类和不同属性的对象
*/
// 使用 constructor 属性一例
function User(){

}
// 创建user一个实例
var me = new User();
// 我们在创建一个新的user对象【使用上面对象的constructor】
var you = new me.constructor();
// 打印出来是可以看到他们俩的constructor 指向的是同一个对象
// console.log(me.constructor === you.constructor);

/**
* 公有方法
*/
// 公有方法可以完全地被对象的上下文中最终的使用者访问
// 为了实现对象的所有实例都可以共用的方法需要使用prototype属性
// prototype 简单地包含一个对象,为一个父对象的所有新副本充当对基类的引用。本质上,prototype 的任何属性对该对象的所每一个实例都是可用的。创建/引用的过程给了我们一个廉价版的继承

// 由于对象的 prototype 也是一个对象,就跟其它任何对象一样,你可以给它附加新的属性。附加给 prototype 的新的属性将成为从原来的 prototype 对象实例化的每个对象的一部分,有效地使得该属性成为公有的(且可为全部实例所访问)

// demo
// 创建一个新的User对象
function User(name,age){
this.name = name;
this.age = age;
}
//为 prototype 对象添加一个新方法
User.prototype.getName = function(){
return this.name;
};
//为 prototype 对象添加另一个方法
//注意此方法的上下文将是被实例化的对象
User.prototype.getAge = function(){
return this.age;
};
//实例化一个新的User 对象
var user = new User( "Bob", 44 );
var user2 = new User('zhansan',33);
//我们可以看到两个方法被附加到了对象上,有着正确的上下文
// alert( user.getName() == "Bob" );
// alert( user.getAge() == 44 );

/**
* 私有方法
*/
// 私有方法和变量只能被其它的私有方法、私有变量的特权方法访问
// 这是一种定义只能在对象内部访问的代码的方式

//demo
// 声明一个表示教室的对象
function Classroom(student,teacher){
// 课程数据存储在共有的属性中
this.s = student;
this.t = teacher;
var stu = student;
// console.log(this.s);
// 用来显示教室中所有学生的私有方法[不return的话 只能在内部调用]
function disp(){
this.disstu = student;
// console.log(this.s); //undefined
// console.log(stu);
// console.log(this.disstu);
}
disp();
}
var clas = new Classroom(['zhangsan','lisi','wangwu'],'teacher');
// clas.disp() //clas.disp is not a function
// Classroom.disp() //Classroom.disp is not a function

// 尽管很简单,私有方法却是非常重要的,它可以在保持你的代码免于冲突同时允许对你的用户可见和可用的施以更强大的控制

/**
* 特权方法
*/
// 指的是那种能够观察和维护私有变量而又可以作为一种公有方法被用户访问的方法
function User(name,age){
// 计算用户的出生年份
var year = (new Date()).getFullYear() - age;
// 创建一个特权方法 对变量year 有访问权【实例出来的对象通过.语法也可以访问】
this.getYearBorn = function(){
return year;
};
}
// 创建一个实例
var user = new User('庞成勇',23);
// console.log(user.getYearBorn() === 1993);
// console.log(User.getYearBorn());//User.getYearBorn is not a function
// console.log(user.year);//undefined

// 本质上,特权方法是动态生成的方法,因为它们是在运行时而不是代码初次编译时添加给对象的。这种技术在计算量上要比绑定一个简单的方法到对象的 prototype 上来得昂贵,但同时也的强大和灵活得多。

// 动态生成的方法可以实现什么
// 创建一个新的接受 properties 对象的对象
//创建一个新的接受 properties 对象的对象
function User( properties ) {
//遍历对象属性,确保它作用域正确(如前所述)
for ( var i in properties ) {

(function(which){
var p=i
//为属性创建获取器
which[ "get" + i ] = function() {
return properties[p];
};
//为属性创建设置器
which[ "set" + i ] = function(val) {
properties[p] = val;
};

})(this);
}
}
//创建一个新 user 对象实例,传入一个包含属性的对象作为种子
var user = new User({
name: "Bob",
age: 44
});
//请注意 name 属性并不存在,因为它在 properties 对象中,是私有的
alert( user.name == null );
//然而,我们能够使用用动态生成的方法 getname 来访问它
alert( user.getname() == "Bob" );
//最后,我们能看到,通过新生成的动态方法设置和获取 age 都是可以的
user.setage( 22 );
alert( user.getage() == 22 );

/**
* 静态方法
*/
/*静态方法背后的前提其实跟其它任何方法是一样的。然而,最主要的不同在于,这些方
法作为对象的静态属性而存在。作为属性,它们在该对象的实例上下文中不可访问;它们只
有在与主对象本身相同的上下文是可用的。这些与传统的类继承的相似点,使得他们有点像
是静态的类方法。
实际上,以这种方式编写代码的唯一好处在于,这种方法保持对象名称空间的干净*/

//附加在User 对象上的一个静态方法
User.cloneUser = function( user ) {
//创建并返回一个新的User 对象
return new User(
//该对象是其它 user 对象的克隆
user.getName(),
user.getAge()
);
}
// 静态方法是我们遇到的第一种纯粹以组织代码为目的的方法。

// 封装 代码片段
var test = (function(arg) {
'use strict';

// 定义静态私有变量
var name = '静态私有变量privatename';
// 定义静态私有函数
var privetefun = function (){
console.log('静态私有函数privetefun');
}

// console.log(this)  undefined

// 构造函数
function test(arg) {
console.log(this)
// enforces new

if (!(this instanceof test)) {
return new test(arg);
}

// 调用私有函数以及变量
// privetefun()
// console.info(name)

var names='私有变量names',Id;
function checkName(name){
console.warn('检测name'+names)
}
// checkName();

// 调用静态共有方法
// test.getName();

// 公有的对象属性
this.ass = '1'
// console.log(this.ass);
// 定义特权方法【在外部可以通过实例访问】
this.getId = function(){
console.info('特权方法获取ID:'+Id);
}

// 定义构造器
this.setId =function(agr){
Id = agr;
};
// 调用构造器
this.setId('11111111')
}

// 定义静态共有属性
test.staName = '静态共有属性';
// 静态共有方法
test.getName = function(){
console.log(name) // 访问私有变量
console.log(this.staName) // 访问静态共有属性
console.log(test.staName) // 访问静态共有属性
}

// 在原型链上声明
test.prototype = {
// 静态共有属性
isPublic:true,
// 静态共有方法
getPriveteName:function(){
console.log(name)
test.getName()
}
};

return test;

}());
// var a = new test('aaaaaaa');
// a.getPriveteName()  // 访问原型链共有
// a.getId();// 访问特权方法
// console.log(a.ass); // 访问共有属性
</script>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息