js高级学习笔记(一)

面向对象、创建对象、原型….

(注:部分内容是来自所学视频里的内容)

面向对象的三大特性

一、封装

举个小例子来说明封装的必要性、
(1)在没有面向对象封装前我们是这样写代码的

var divs = document.getElementsByTagName( 'div' );

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

    divs[i].style.border = "1px dotted black";

}

然而,当你要获取其它的标签或是遍历获取到的标签,你就会重复上面的代码,当然也有几个单词不一样的啦,但是你不觉得你在做无用功吗?而且让你的代码看上去很冗余繁杂,你的工作伙伴也不愿意和你合作哒。So,有了面向对象的思想进行封装就好办了,下面请看这段代码….

var itcast = { 
    //获取元素模块
    getEle: { 
        tag: function (tagName) { 
            return document.getElementsByTagName(tagName); 
        }, 
        id: function (idName) { 
            return document.getElementById(idName); 
        } 
    }, 
    //设置css模块   
    setCss: { 
        setStyle: function (arr) { 
            for(var i = 0; i < arr.length; i++) { 
                arr[i].style.border = "1px solid #abc"; 
            } 
        }, 
        css: function() {}, 
        addClass: function() {}, 
        removeClass: function() {} 
        // ... 
    } 

};

var divs = itcast.getEle.tag(div);
itcast.setCss.setStyle(divs);

这样看起来是不是简单明了了很多,也不会有重复的代码。

二、继承

JavaScript当中继承是指一个对象没有一些属性和方法,把另外有一个对象的属性和方法,拿过来自己用。

(1)混入式继承 for in
var obj = {};
var obj1= {
    name : "继承",
    sayHello: function() {

        console.log("你好,我是继承");
    }
}

for(var k in obj1){
    //obj1[k]可以获取到对象的每一个属性
    //这里使用k给对象新增属性的时候不可以使用点语法
    obj[k]=obj1[k];
}
console.log(obj);
(2)原型继承(利用共享)
//(1)给原型对象添加新成员
function Person(name,age) {
    this.name=name;
    this.age=age;
}
Person.prototype.sayHello=function(){
    alert(this.name+"你好");
}
var p=new Person("GJ", 18);
p.sayHello();

//(2)直接替换原型对象
function Person(name,age) {
    this.name=name;
    this.age=age;
}
var sister={
    sayHello : function(){
        alert(this.name+"你好");
    }
}
Person.prototype=sister;
var p=new Person("GJ", 18);
p.sayHello();

//(3)利用混入的方式给原型对象添加成员
function Person(name,age) {
    this.name=name;
    this.age=age;
}
var sister={
    sayHello : function(){
        alert(this.name+"你好");
    }
}

for(var i in sister){
    Person.prototype[i]=sister[i];
}
var p=new Person("GJ", 18);
p.sayHello();
//注意:这种方式很可能把原型中的原有的对象给替换掉
(3)原型继承的作用
————1)扩展内置对象
function MyArray(){
    //就可以在这里面添加你想添加的方法了(在下面继承了所有的Array属性和方法)
}
MyArray.prototype= [];
var NewArray=new MyArray();
NewArray.push(1);
NewArray.push(2,3,4);
alert(NewArray);

三、多态

js中没有相应的体现,在强类型语言中比较常用。
简而言之,就是使用父类的变量接受子类的对象。

创建对象的方式

(1)对象字面量

缺陷:只能创建一次对象,复用性较差,如果创建多个对象代码冗余度太高

var obj = {
    name: "字面量",
    type: "Object",

}
(2)使用构造函数

缺陷:想创建一个类似的对象,就会产生大量的代码

var box=new Object();
box.name='GJ';
box.age='18';
box.run=function() {
 return this.name+this.age+'运行中。。。'
}
(3)封装简单的工厂函数(不推荐使用)

它解决了重复实例化问题,但还有个识别问题,因为根本无法搞清楚他们到底是哪个对象的实例

function createBox(name,age) {
    var obj=new object();
    obj.name= name;
    obj.age=age;
    box.run=function() {
     return this.name+this.age+'运行中。。。'
    }
    return obj;
}
var obj = createBox('Gj',18);
(4)自定义构造函数

既解决了重复实例化的问题,又解决了对象识别的问题
默认返回的是新创建的对象,如果我们自己写的return语句,return的是空值或是基本数据类型,返回的都是新创建的对象;如果返回的是object类型的值,将取而代之

function Box(name,age) {
    this.name=name;
    this.age=age;
    this.run=function() {
         return this.name+this.age+'运行中。。。'
    }
}
var box1=new Box('GJ',100);
alert(box1.run());
(5)原型
  • 原型是什么?
    ——-在构造函数创建出来的时候,系统会默认的帮构造函数创建并关联一个原型
  • 原型可以用来做什么?
    ——-原型中的属性和方法可以被使用该构造函数创建出来的对象使用
  • 如何访问构造函数的原型
    ——-构造函数.prototype
  • 如何给原型对象添加属性和方法
    ——–使用对象的动态特性
    注意:当使用对象去访问属性和方法的时候,首先在对象自己内部查找,如果找到就直接使用,如果没有找到就用原型。
function Person(name,status) {
    this.name=name;
    this.status=status;
    this.act=function(){
        console.log("原型")
    }
}
var p = new Person("xyz","single");

Person.prototype.move = function() {
    console.log("我要做运动");
}
p.move();
(6)使用原型注意事项
  • 使用对象访问属性的时候,如果在本身内找不到就去原型中查找。但是使用点语法进行属性复值得时候并不会去原型中查找,对象中不存在该属性,就会给该对象新增该属性,如果在对象中有这个属性,修改这个属性
  • 如果在原型中的属性是引用类型的属性,那么所有的对共享该属性,并且一个对象修改了该引用类型属性中的成员,则其他所有跟这个原型对象相关的对象都会受到影响
  • 一般情况下原型中只会放需要共享的方法。
(7)原型链
1.什么是原型链?
    每个构造函数都有原型对象
    每个对象都会有构造函数
    每个构造函数的原型都是一个对象
    那么这个原型对象也会有构造函数
    那么这个原型对象的构造函数也会有原型对象
    这样就会形成一个链式的结构,称为原型链
2.原型链结构的基本形式
function Person(name){
    this.name=name;
}
var w=new Person();

//p ---> Person.prototype --->Object.prototype---->null

属性搜索的原则
——1.当访问一个对象的成员的时候,会先在自身找有没有,如果找到直接使用,
——2.如果没有找到,则去当前对象的原型对象中去查找,如果找到了直接使用,
——3.如果没有找到,继续找原型对象的原型对象,如果找到了,直接使用
——4.如果没有找到,则继续向上查找,直到Object.prototype,如果还是没有,就报错

(8) Object.prototype常用成员
成员描述
Object.prototype.proto指向当对象被实例化的时候,用作原型的对象。
Object.prototype.hasOwnProperty()返回一个布尔值 ,表示某个对象是否含有指定的属性,而且此属性非原型链继承的。
Object.prototype.isPrototypeOf()返回一个布尔值,表示指定的对象是否在本对象的原型链中。
Object.prototype.toString()返回对象的字符串表示。
Object.prototype.valueOf()返回指定对象的原始值。

补充

一. function的使用

(一)语法

———– Function函数所有的参数全都是字符串
———– Function函数的作用就是将所有的参数组合起来,变成一个函数
———– 1、如果只传一个参数,那么这个函数必然是函数体
———– 2、如果传多个参数,那么最后一个参数表示函数体,前面的参数代表将要创建的函数的参数
———– 3、如果不传参数,表示创建一个空函数

// 练习: 利用 Function 创建一个求三个数中最大数的函数.
var max = new Function("a", "b", "c", "return (a > b ? a : b)> c ? (a > b? a : b):c;");
(二)怎么解决function中代码过长问题

1.可以使用字符串拼接 让代码换行

 var max = new Function("arr",
         "var maxNum = arr[0];" +
         "for(var i = 1;i<arr.length;i++){" +
         "if(maxNum < arr[i]){" +
         "maxNum = arr[i];" +
         "}" +
         "}" +
         "return maxNum;"
 )

 console.log(max([1, 2, 3, 44, 5, 6]));

2.使用模板的方式,将代码写在模板标签内,获取该标签的内容

 window.onload =function () {
     var script = document.getElementById("funcContent");
     var str = script.innerHTML;
     var max = new Function("arr", str);
     console.log(max([1, 2, 3, 44, 5, 6]));
 }

 <script type="text/template" id="funcContent">
    var maxNum = arr[0];
    for(var i = 1; i<arr.length; i++){
        if(maxNum < arr[i]){
            maxNum = arr[i];
        }
    }
    return maxNum;
</script>

3.使用反引号(`) 引住字符串,那么就可以 换行了

ES6 语法(很少有浏览器实现) 使用键盘左上角的` 表示可换行字符串的界定符,之前我们用的是单引号或者双引号来表示一个字符串字面量,在ES6中可以用反引号来表示该字符串可换行。

//这是es6中的语法,存在兼容性问题

 var str = `adfafdsa
            asdfas`;

        console.log(str);
(三)function和eval的区别

首先来说下eval
eval函数可以用来将字符串转换成JavaScript代码并且运行
var str = “var a = 10”;
eval(str);
console.log(a);
使用eval来解析JSON格式字符串的时候,会将{}解析为代码块,而不是对象的字面量,解决办法是:
1.在JSON格式的字符串前面拼接上 “var o =”
2.把JSON格式的字符串使用()括起来,就不会将{}解析为代码块,而是表达式

var jsonData = '({"name":"zs", "age":18})';
  var o = JSON.parse(jsonData);
     console.log(o);

eval("var o = "+ jsonData);
var o = eval(jsonData);
console.log(o);

1.共同点:都可以将字符串转换成js代码
2.不同点:
1)function创建出来的是函数并不会直接调用,只有当手动去调用才可以执行
2)eval把字符串转成代码之后,直接就执行

(四)arguments

函数内部的一个对象,在函数调用的时候,默认的会将所有传入的实参依次存入该对象(一个伪数组)
arguments.length:可以用来表示传入的实参的个数

(五)静态成员和实例成员

静态成员:是指构造函数的属性和方法
实例成员:是指实例的属性和方法

function Person(){
    this.name = "zs",
    this.sayHello = function(){
        console.log("Hello World");
    }
}

//下面这个sayHi方法就是构造函数自己的方法,也就是静态方法
Person.sayHi = function(){
    console.log("I'm a Person");
}

//原型属性属于构造函数,所以原型属性是静态属性
Person.prototype = {};
var p = new Person();

//这里的name是构造函数创建出来的实例对象的属性,所以是实例属性
p.name = "GJ";


//这里的sayHello也是构造函数创建出来的实例对象的方法,所以是实例方法
p.sayHello();


//在jQuery中,$("#id")是一个实例,所以它们都是实例成员
$("#id").css();
$("#id").text();

//像这种是jQuery内部的工具方法,属于静态方法
$.trim();
$.each();
$.extend();

//把工具方法,作为静态成员
//把跟对象相关的方法,作为实例成员

前端小白:所记内容有什么不对或是要完善的地方还望指出,感激不尽
小Tip:后期还会进行修改和补充

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值