本文共 5956 字,大约阅读时间需要 19 分钟。
1.字面量
//字面量创建对象var p1 = { name: '张三', age: 18}
2.构造函数
//构造函数创建对象1. function Person() { this.name = '张三'; this.age = 18; } 2. function Person(name,age) { this.name = name; this.age = age; }var p1 = new Person('张三', 18)//实例化对象
构造函数方法很好用,但是存在一个浪费内存的问题。
这样做有一个很大的弊端,每一次生成一个实例,多占用一些内存。这样既不环保,也缺乏效率。
解决方法:
function Person(name, age) { this.name = name; this.age = age; }// 将方法定义到原型上Person.prototype.speak = function () { console.log("hello world");};var p1 = new Person("李白", 10);var p2 = new Person("杜甫", 8);console.log(p1.speak === p2.speak); // true
3.类
class Person{ constructor(name,age){ this.name=name this.age=age }}var p1=new Person('张三',18)
Javascript规定,每一个构造函数都有一个prototype
属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。 这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上。__proto__
是原型链,指向实例化的函数原型。
Car.prototype={ constructor:Car, run:function(){ console.log('runrunrun!'); } } var c1=new Car('red'); console.log(Car.prototype===c1.__proto__);//true
每一个函数都有一个原型属性prototype(对象属性),里面放置的是共有、公有的属性或者方法。(一般情况属性是私有的)。注意,只有函数才有prototyoe属性
function Person() { } var p = new Person() console.log(Person.prototype); // Object{} console.log(p.prototype); //undefined
constructor 主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。
如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数如:
实例对象与原型之间的连接,叫做原型链。proto( 隐式连接 )
JS在创建对象的时候,都有一个叫做proto的内置属性,用于指向创建它的函数对象的原型对象prototype。 内部原型(proto)和构造器的原型(prototype) 1、每个对象都有一个proto属性,原型链上的对象正是依靠这个属性连结在一起 2、作为一个对象,当你访问其中的一个属性或方法的时候,如果这个对象中没有这个 方法或属性,那么Javascript引擎将会访问这个对象的proto属性所指向上一个对 象,并在那个对象中查找指定的方法或属性,如果不能找到,那就会继续通过那个对象 的proto属性指向的对象进行向上查找,直到这个链表结束。静态成员 在构造函数本身上添加的成员,与具体的对象无关
function foo(){ this.show = function(){ return this; }}foo.test = 123; //静态属性foo.say = function(){ return this;}foo.say();var fn = new foo(); //实例化的新的对象,this指向这个新的对象,不能访问类的静态方法fn.say(); //Noname1.html:45 Uncaught TypeError: fn.say is not a functionconsole.log(foo.say() == fn.say());
作用:代码重复使用
function Car() { console.log(this); // Person } function Person(name) { this.name = name; } var p1 = new Person(123); Car.call(p1);
call方法
调用函数
function f1(){ console.log('f1');}f1.call()
修改 this 指向
function Car() { console.log(this); // Person}function Person(name) { this.name = name;}var p1 = new Person(123);Car.call(p1);
1.函数声明方式 function 关键字 (命名函数)
function fn(){}
2.函数表达式(匿名函数)
var fn = function(){}
3.new Function()
var fn = new Function('参数1','参数2'..., '函数体')
/* 1. 普通函数 */function fn() { console.log('放假');}fn();/* 2. 对象的方法 */var c = { sayHi: function() { console.log('放假'); }}c.sayHi();/* 3. 构造函数*/function Star() {};new Star();/* 4. 绑定事件函数*/btn.onclick = function() {}; // 点击了按钮就可以调用这个函数/* 5. 定时器函数*/setInterval(function() {}, 1000); 这个函数是定时器自动1秒钟调用一次/* 6. 立即执行函数(自调用函数)*/(function() { console.log('放假');})();
1.在普通函数中,this指windowfunction f1() { console.log(this); //window}f1()2.在构造函数中,this指实例对象function Car(name) { this.name = name console.log(this); //car this.run = function () { console.log(this); //car }}var c1 = new Car( 'ddd ' )c1.run()3.在对象中,this指的是这个对象var obj = { aa: 11,bb: 22, cc : function () { console.log(this); //obj }}obj.cc();4.元素绑定事件中,this指的是绑定事件对象btn.addEventListener( ' click ', function () { console.log(this); //btn})5.定时器中,this指windowsetInterval(console.log(this), 1000);//window6.立即执行函数中,this指window(function(){ console.log(this);//window})()//立即函数前一个语句结束必须加;
call方法
call()方法调用一个对象。简单理解为调用函数的方式,但是它可以改变函数的 this 指向var o = {name: 'andy'}function fn(a, b) {console.log(this);console.log(a b)};fn(1,2)// 此时的this指向的是window 运行结果为3fn.call(o,1,2)//此时的this指向的是对象o,参数使用逗号隔开,运行结果为3
apply方法
apply() 方法调用一个函数。简单理解为调用函数的方式,但是它可以改变函数的 this 指向。var o = {name: 'andy'}function fn(a, b) {console.log(this);console.log(a b)};fn(1,2)// 此时的this指向的是window 运行结果为3fn.apply(o,[1,2])//此时的this指向的是对象o,参数使用逗号隔开,运行结果为3
apply()用法和call()基本相同,但是传参不同,call传参用逗号隔开,apply传递到的是数组
bind方法
bind() 方法不会调用函数,但是能改变函数内部this 指向,返回的是原函数改变this之后产生的新函数 如果只是想改变 this 指向,并且不想调用这个函数的时候,可以使用bindvar o = {name: 'andy'};function fn(a, b) { console.log(this); console.log(a b);};var f = fn.bind(o, 1, 2); //此处的f是bind返回的新函数f();//调用新函数 this指向的是对象o 参数使用逗号隔开
注意点:
call 和 apply 会调用函数, 并且改变函数内部this指向.call 和 apply传递的参数不一样,call传递参数使用逗号隔开,apply使用数组传递bind 会返回新的函数,而不会调用函数
//方式一:通过调用RegExp对象的构造函数创建var p = new RegExp(/123/);//方式二:利用字面量创建 正则表达式var p2 = /abc/;
test() 正则对象方法,用于检测字符串是否符合该规则,该对象会返回 true 或 false,其参数是测试字符
串。边界符 | 说明 |
---|---|
^ | 以什么开头 |
$ | 以什么结尾 |
如果 ^和 $ 在一起,表示必须是精确匹配。
//检测正则表达式console.log(p.test(123));//trueconsole.log(p2.test('abc'));//trueconsole.log(p2.test('azbzc'));//falseconsole.log('----------------------');var p3 = /^a254b$/;//精确匹配console.log(p3.test('a254b'));//trueconsole.log(p3.test('a123b'));//false
[]只要有其中一个就可以
var p4 = /[abc123]/;//[]只要包含其中一个就可以console.log(p4.test('zxfhas'));//truevar reg = /^[a-z]$/ //26个英文字母任何一个字母返回 true - 表示的是a 到z 的范围console.log(reg.test('a'));//trueconsole.log(reg.test('z'));//trueconsole.log(reg.test('A'));//false
量词 | 说明 |
---|---|
* | 重复0次或更多次 |
重复1次或更多次 | |
? | 重复0次或1次 |
{n} | 重复n次 |
{n,} | 最少重复n次,最多无限 |
{n,m} | 最少重复n次,最多重复m次 |
var p5 = /a /;console.log(p5.test('cccc'));//falseconsole.log(p5.test('accc'));//truevar p6 = /a{2,3}/;console.log(p6.test('aa'));//true
1.大括号 量词符. 里面表示重复次数
2.中括号 字符集合。匹配方括号中的任意字符. 3.小括号表示优先级预定类 | 说明 |
---|---|
\d | 匹配0-9之间的任意数字 |
\D | 匹配0-9以外的字符 |
\w | 匹配任意的字母、数字和下划线 |
\W | 除所有的字母、数字和下划线以外的字符 |
\s | 匹配空格(包括换行符、空格符等) |
\S | 匹配非空格的字符 |
var p7 = /\d/; console.log(p7.test(0));//true
replace() 方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则表达式。
var str = 'abc和123';//当正则表达式满足条件是,才会替换var newStr = str.replace(/abc/, 'zzz');console.log(newStr)//zzz和123var str2 = 'abcaaa';//替换所有的avar newStr2 = str2.replace(/a/g, '2');console.log(newStr2)//2bc222var str3 = 'abcAba';//替换所有的a,不区分大小写var newStr3 = str3.replace(/a/gi, '?');console.log(newStr3)//?bc?b?
转载地址:http://tfrji.baihongyu.com/